]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'core-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Oct 2008 22:17:40 +0000 (15:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Oct 2008 22:17:40 +0000 (15:17 -0700)
* 'core-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  do_generic_file_read: s/EINTR/EIO/ if lock_page_killable() fails
  softirq, warning fix: correct a format to avoid a warning
  softirqs, debug: preemption check
  x86, pci-hotplug, calgary / rio: fix EBDA ioremap()
  IO resources, x86: ioremap sanity check to catch mapping requests exceeding, fix
  IO resources, x86: ioremap sanity check to catch mapping requests exceeding the BAR sizes
  softlockup: Documentation/sysctl/kernel.txt: fix softlockup_thresh description
  dmi scan: warn about too early calls to dmi_check_system()
  generic: redefine resource_size_t as phys_addr_t
  generic: make PFN_PHYS explicitly return phys_addr_t
  generic: add phys_addr_t for holding physical addresses
  softirq: allocate less vectors
  IO resources: fix/remove printk
  printk: robustify printk, update comment
  printk: robustify printk, fix #2
  printk: robustify printk, fix
  printk: robustify printk

Fixed up conflicts in:
arch/powerpc/include/asm/types.h
arch/powerpc/platforms/Kconfig.cputype
manually.

1297 files changed:
Documentation/00-INDEX
Documentation/ABI/testing/sysfs-profiling [new file with mode: 0644]
Documentation/DocBook/Makefile
Documentation/DocBook/procfs-guide.tmpl
Documentation/DocBook/procfs_example.c
Documentation/DocBook/videobook.tmpl [deleted file]
Documentation/HOWTO
Documentation/SAK.txt
Documentation/SubmitChecklist
Documentation/SubmittingDrivers
Documentation/SubmittingPatches
Documentation/block/data-integrity.txt
Documentation/cris/README
Documentation/development-process/1.Intro [new file with mode: 0644]
Documentation/development-process/2.Process [new file with mode: 0644]
Documentation/development-process/3.Early-stage [new file with mode: 0644]
Documentation/development-process/4.Coding [new file with mode: 0644]
Documentation/development-process/5.Posting [new file with mode: 0644]
Documentation/development-process/6.Followthrough [new file with mode: 0644]
Documentation/development-process/7.AdvancedTopics [new file with mode: 0644]
Documentation/development-process/8.Conclusion [new file with mode: 0644]
Documentation/dontdiff
Documentation/fb/intelfb.txt
Documentation/fb/uvesafb.txt
Documentation/fb/viafb.modes [new file with mode: 0644]
Documentation/fb/viafb.txt [new file with mode: 0644]
Documentation/feature-removal-schedule.txt
Documentation/filesystems/autofs4-mount-control.txt [new file with mode: 0644]
Documentation/filesystems/ext3.txt
Documentation/filesystems/nfsroot.txt
Documentation/filesystems/proc.txt
Documentation/filesystems/ramfs-rootfs-initramfs.txt
Documentation/gpio.txt
Documentation/ia64/kvm.txt
Documentation/kernel-parameters.txt
Documentation/kobject.txt
Documentation/networking/cs89x0.txt
Documentation/networking/phonet.txt
Documentation/networking/vortex.txt
Documentation/power/s2ram.txt
Documentation/powerpc/00-INDEX
Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/dma.txt
Documentation/powerpc/dts-bindings/fsl/ssi.txt
Documentation/powerpc/ppc_htab.txt [deleted file]
Documentation/powerpc/smp.txt [deleted file]
Documentation/scsi/ChangeLog.megaraid
Documentation/spi/pxa2xx
Documentation/w1/00-INDEX
Documentation/w1/masters/ds2490
Documentation/w1/slaves/00-INDEX [new file with mode: 0644]
Documentation/w1/slaves/w1_therm [new file with mode: 0644]
Documentation/w1/w1.generic
MAINTAINERS
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/a.out.h
arch/alpha/include/asm/elf.h
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/smp.c
arch/arm/Makefile
arch/arm/configs/omap3_beagle_defconfig [new file with mode: 0644]
arch/arm/configs/omap_ldp_defconfig [new file with mode: 0644]
arch/arm/configs/overo_defconfig [new file with mode: 0644]
arch/arm/include/asm/elf.h
arch/arm/mach-integrator/cpu.c
arch/arm/mach-omap1/clock.c
arch/arm/mach-omap1/clock.h
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap1/mcbsp.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-ldp.c [new file with mode: 0644]
arch/arm/mach-omap2/board-omap3beagle.c [new file with mode: 0644]
arch/arm/mach-omap2/board-overo.c [new file with mode: 0644]
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clock24xx.h
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/clock34xx.h
arch/arm/mach-omap2/clockdomain.c [new file with mode: 0644]
arch/arm/mach-omap2/clockdomains.h [new file with mode: 0644]
arch/arm/mach-omap2/cm-regbits-24xx.h
arch/arm/mach-omap2/cm-regbits-34xx.h
arch/arm/mach-omap2/cm.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/mcbsp.c
arch/arm/mach-omap2/memory.c
arch/arm/mach-omap2/memory.h
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/powerdomain.c [new file with mode: 0644]
arch/arm/mach-omap2/powerdomains.h [new file with mode: 0644]
arch/arm/mach-omap2/powerdomains24xx.h [new file with mode: 0644]
arch/arm/mach-omap2/powerdomains34xx.h [new file with mode: 0644]
arch/arm/mach-omap2/prcm-common.h
arch/arm/mach-omap2/prm-regbits-24xx.h
arch/arm/mach-omap2/prm-regbits-34xx.h
arch/arm/mach-omap2/prm.h
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/sleep24xx.S [moved from arch/arm/mach-omap2/sleep.S with 85% similarity]
arch/arm/mach-omap2/sram34xx.S [new file with mode: 0644]
arch/arm/mach-pxa/cm-x270.c
arch/arm/mach-pxa/cpufreq-pxa2xx.c
arch/arm/mach-pxa/cpufreq-pxa3xx.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-s3c2410/bast-irq.c
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/include/mach/debug-macro.S
arch/arm/mach-s3c2410/include/mach/map.h
arch/arm/mach-s3c2410/include/mach/spi.h
arch/arm/mach-s3c2410/include/mach/uncompress.h
arch/arm/mach-s3c2410/irq.c
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/mach-otom.c
arch/arm/mach-s3c2410/mach-qt2410.c
arch/arm/mach-s3c2410/mach-smdk2410.c
arch/arm/mach-s3c2410/mach-tct_hammer.c
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-s3c2410/pm.c
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2410/sleep.S
arch/arm/mach-s3c2410/usb-simtec.c
arch/arm/mach-s3c2412/clock.c
arch/arm/mach-s3c2412/dma.c
arch/arm/mach-s3c2412/irq.c
arch/arm/mach-s3c2412/mach-jive.c
arch/arm/mach-s3c2412/mach-smdk2413.c
arch/arm/mach-s3c2412/mach-vstms.c
arch/arm/mach-s3c2412/pm.c
arch/arm/mach-s3c2412/s3c2412.c
arch/arm/mach-s3c2440/clock.c
arch/arm/mach-s3c2440/dma.c
arch/arm/mach-s3c2440/dsc.c
arch/arm/mach-s3c2440/irq.c
arch/arm/mach-s3c2440/mach-anubis.c
arch/arm/mach-s3c2440/mach-at2440evb.c
arch/arm/mach-s3c2440/mach-nexcoder.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/arm/mach-s3c2440/mach-rx3715.c
arch/arm/mach-s3c2440/mach-smdk2440.c
arch/arm/mach-s3c2440/s3c2440.c
arch/arm/mach-s3c2442/clock.c
arch/arm/mach-s3c2442/s3c2442.c
arch/arm/mach-s3c2443/clock.c
arch/arm/mach-s3c2443/dma.c
arch/arm/mach-s3c2443/irq.c
arch/arm/mach-s3c2443/mach-smdk2443.c
arch/arm/mach-s3c2443/s3c2443.c
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mm/Kconfig
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/common.c
arch/arm/plat-omap/devices.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/mach/board-2430sdp.h
arch/arm/plat-omap/include/mach/board-apollon.h
arch/arm/plat-omap/include/mach/board-h4.h
arch/arm/plat-omap/include/mach/board-ldp.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/board-omap3beagle.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/board-overo.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/board.h
arch/arm/plat-omap/include/mach/clock.h
arch/arm/plat-omap/include/mach/clockdomain.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/common.h
arch/arm/plat-omap/include/mach/control.h
arch/arm/plat-omap/include/mach/cpu.h
arch/arm/plat-omap/include/mach/debug-macro.S
arch/arm/plat-omap/include/mach/entry-macro.S
arch/arm/plat-omap/include/mach/fpga.h
arch/arm/plat-omap/include/mach/gpio.h
arch/arm/plat-omap/include/mach/gpmc.h
arch/arm/plat-omap/include/mach/hardware.h
arch/arm/plat-omap/include/mach/io.h
arch/arm/plat-omap/include/mach/irqs.h
arch/arm/plat-omap/include/mach/mcbsp.h
arch/arm/plat-omap/include/mach/memory.h
arch/arm/plat-omap/include/mach/mux.h
arch/arm/plat-omap/include/mach/omap1510.h
arch/arm/plat-omap/include/mach/omap16xx.h
arch/arm/plat-omap/include/mach/omap24xx.h
arch/arm/plat-omap/include/mach/omapfb.h
arch/arm/plat-omap/include/mach/pm.h
arch/arm/plat-omap/include/mach/powerdomain.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/sdrc.h
arch/arm/plat-omap/include/mach/serial.h
arch/arm/plat-omap/include/mach/sram.h
arch/arm/plat-omap/include/mach/system.h
arch/arm/plat-omap/io.c [new file with mode: 0644]
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/sram.c
arch/arm/plat-s3c/Makefile [new file with mode: 0644]
arch/arm/plat-s3c/include/plat/debug-macro.S [moved from include/asm-arm/plat-s3c/debug-macro.S with 97% similarity]
arch/arm/plat-s3c/include/plat/map.h [moved from include/asm-arm/plat-s3c/map.h with 100% similarity]
arch/arm/plat-s3c/include/plat/regs-adc.h [moved from include/asm-arm/plat-s3c/regs-adc.h with 100% similarity]
arch/arm/plat-s3c/include/plat/regs-serial.h [moved from include/asm-arm/plat-s3c/regs-serial.h with 100% similarity]
arch/arm/plat-s3c/include/plat/regs-timer.h [moved from include/asm-arm/plat-s3c/regs-timer.h with 100% similarity]
arch/arm/plat-s3c/include/plat/uncompress.h [moved from include/asm-arm/plat-s3c/uncompress.h with 98% similarity]
arch/arm/plat-s3c24xx/clock.c
arch/arm/plat-s3c24xx/common-smdk.c
arch/arm/plat-s3c24xx/cpu.c
arch/arm/plat-s3c24xx/devs.c
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-s3c24xx/include/plat/clock.h [moved from include/asm-arm/plat-s3c24xx/clock.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/common-smdk.h [moved from include/asm-arm/plat-s3c24xx/common-smdk.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/cpu.h [moved from include/asm-arm/plat-s3c24xx/cpu.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/devs.h [moved from include/asm-arm/plat-s3c24xx/devs.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/dma.h [moved from include/asm-arm/plat-s3c24xx/dma.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/irq.h [moved from include/asm-arm/plat-s3c24xx/irq.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/pm.h [moved from include/asm-arm/plat-s3c24xx/pm.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/s3c2400.h [moved from include/asm-arm/plat-s3c24xx/s3c2400.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/s3c2410.h [moved from include/asm-arm/plat-s3c24xx/s3c2410.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/s3c2412.h [moved from include/asm-arm/plat-s3c24xx/s3c2412.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/s3c2440.h [moved from include/asm-arm/plat-s3c24xx/s3c2440.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/s3c2442.h [moved from include/asm-arm/plat-s3c24xx/s3c2442.h with 100% similarity]
arch/arm/plat-s3c24xx/include/plat/s3c2443.h [moved from include/asm-arm/plat-s3c24xx/s3c2443.h with 100% similarity]
arch/arm/plat-s3c24xx/irq.c
arch/arm/plat-s3c24xx/pm-simtec.c
arch/arm/plat-s3c24xx/pm.c
arch/arm/plat-s3c24xx/pwm-clock.c
arch/arm/plat-s3c24xx/pwm.c
arch/arm/plat-s3c24xx/s3c244x-clock.c
arch/arm/plat-s3c24xx/s3c244x-irq.c
arch/arm/plat-s3c24xx/s3c244x.c
arch/arm/plat-s3c24xx/sleep.S
arch/arm/plat-s3c24xx/time.c
arch/avr32/include/asm/elf.h
arch/avr32/mach-at32ap/cpufreq.c
arch/blackfin/configs/BF526-EZBRD_defconfig
arch/blackfin/configs/BF527-EZKIT_defconfig
arch/blackfin/configs/BF533-EZKIT_defconfig
arch/blackfin/configs/BF533-STAMP_defconfig
arch/blackfin/configs/BF537-STAMP_defconfig
arch/blackfin/configs/BF548-EZKIT_defconfig
arch/blackfin/configs/BF561-EZKIT_defconfig
arch/blackfin/configs/CM-BF527_defconfig
arch/blackfin/configs/CM-BF533_defconfig
arch/blackfin/configs/CM-BF537E_defconfig
arch/blackfin/configs/CM-BF537U_defconfig
arch/blackfin/configs/CM-BF548_defconfig
arch/blackfin/configs/CM-BF561_defconfig
arch/blackfin/include/asm/cacheflush.h
arch/blackfin/include/asm/cplbinit.h
arch/blackfin/include/asm/elf.h
arch/blackfin/include/asm/io.h
arch/blackfin/include/asm/timex.h
arch/blackfin/kernel/cplb-mpu/cplbmgr.c
arch/blackfin/kernel/cplb-nompu/cplbinit.c
arch/blackfin/mach-bf527/head.S
arch/blackfin/mach-bf533/head.S
arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf537/head.S
arch/blackfin/mach-bf548/head.S
arch/blackfin/mach-bf561/head.S
arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
arch/blackfin/mach-common/cache.S
arch/blackfin/mach-common/cpufreq.c
arch/blackfin/mach-common/head.S
arch/cris/arch-v32/mach-a3/cpufreq.c
arch/cris/arch-v32/mach-fs/cpufreq.c
arch/frv/kernel/pm.c
arch/frv/mb93090-mb00/pci-dma-nommu.c
arch/frv/mb93090-mb00/pci-dma.c
arch/frv/mb93090-mb00/pci-frv.c
arch/frv/mb93090-mb00/pci-frv.h
arch/frv/mb93090-mb00/pci-vdk.c
arch/frv/mm/init.c
arch/h8300/Kconfig
arch/h8300/Kconfig.cpu
arch/h8300/include/asm/bug.h
arch/h8300/include/asm/elf.h
arch/h8300/include/asm/io.h
arch/h8300/include/asm/md.h
arch/h8300/include/asm/system.h
arch/h8300/kernel/Makefile
arch/h8300/kernel/module.c
arch/h8300/kernel/time.c
arch/h8300/kernel/timer/Makefile [new file with mode: 0644]
arch/h8300/kernel/timer/itu.c [new file with mode: 0644]
arch/h8300/kernel/timer/timer16.c [new file with mode: 0644]
arch/h8300/kernel/timer/timer8.c [new file with mode: 0644]
arch/h8300/kernel/timer/tpu.c [new file with mode: 0644]
arch/h8300/kernel/traps.c
arch/h8300/mm/fault.c
arch/h8300/platform/h8300h/aki3068net/Makefile
arch/h8300/platform/h8300h/aki3068net/timer.c [deleted file]
arch/h8300/platform/h8300h/generic/Makefile
arch/h8300/platform/h8300h/generic/timer.c [deleted file]
arch/h8300/platform/h8300h/h8max/Makefile
arch/h8300/platform/h8300h/h8max/timer.c [deleted file]
arch/h8300/platform/h8s/edosk2674/Makefile
arch/h8300/platform/h8s/edosk2674/timer.c [deleted file]
arch/h8300/platform/h8s/generic/Makefile
arch/h8300/platform/h8s/generic/timer.c [deleted file]
arch/ia64/Kconfig
arch/ia64/ia32/binfmt_elf32.c
arch/ia64/ia32/ia32_entry.S
arch/ia64/ia32/ia32priv.h
arch/ia64/ia32/sys_ia32.c
arch/ia64/include/asm/elf.h
arch/m32r/kernel/process.c
arch/m68knommu/include/asm/elf.h
arch/mips/Kconfig
arch/mips/bcm47xx/gpio.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/wgt634u.c
arch/mips/emma2rh/common/irq.c
arch/mips/emma2rh/common/prom.c
arch/mips/emma2rh/markeins/platform.c
arch/mips/include/asm/cevt-r4k.h [moved from include/asm-mips/cevt-r4k.h with 100% similarity]
arch/mips/include/asm/elf.h
arch/mips/include/asm/mach-bcm47xx/gpio.h
arch/mips/include/asm/mach-bcm47xx/war.h
arch/mips/include/asm/mach-ip22/ds1286.h [deleted file]
arch/mips/include/asm/mach-ip28/ds1286.h [deleted file]
arch/mips/include/asm/spinlock.h
arch/mips/kernel/linux32.c
arch/mips/kernel/proc.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/vmlinux.lds.S
arch/mips/lasat/sysctl.c
arch/mips/pci/fixup-emma2rh.c
arch/mips/pci/ops-pnx8550.c
arch/mips/pci/pci-emma2rh.c
arch/mips/pci/pci.c
arch/mips/rb532/time.c
arch/mips/sgi-ip22/ip22-platform.c
arch/mips/sgi-ip22/ip22-setup.c
arch/mips/sgi-ip22/ip22-time.c
arch/mips/sgi-ip27/ip27-timer.c
arch/mips/sgi-ip32/ip32-platform.c
arch/mips/sgi-ip32/ip32-setup.c
arch/mips/sibyte/common/sb_tbprof.c
arch/parisc/kernel/binfmt_elf32.c
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall_table.S
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/addnote.c
arch/powerpc/boot/dtc-src/Makefile.dtc
arch/powerpc/boot/dtc-src/checks.c
arch/powerpc/boot/dtc-src/data.c
arch/powerpc/boot/dtc-src/dtc-lexer.l
arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
arch/powerpc/boot/dtc-src/dtc-parser.y
arch/powerpc/boot/dtc-src/dtc.c
arch/powerpc/boot/dtc-src/dtc.h
arch/powerpc/boot/dtc-src/flattree.c
arch/powerpc/boot/dtc-src/fstree.c
arch/powerpc/boot/dtc-src/libfdt_env.h [new file with mode: 0644]
arch/powerpc/boot/dtc-src/livetree.c
arch/powerpc/boot/dtc-src/srcpos.c
arch/powerpc/boot/dtc-src/srcpos.h
arch/powerpc/boot/dtc-src/treesource.c
arch/powerpc/boot/dtc-src/version_gen.h
arch/powerpc/boot/dts/arches.dts [new file with mode: 0644]
arch/powerpc/boot/dts/asp834x-redboot.dts
arch/powerpc/boot/dts/gef_sbc610.dts [new file with mode: 0644]
arch/powerpc/boot/dts/glacier.dts
arch/powerpc/boot/dts/mgcoge.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mgsuvd.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc5121ads.dts
arch/powerpc/boot/dts/mpc8313erdb.dts
arch/powerpc/boot/dts/mpc8315erdb.dts
arch/powerpc/boot/dts/mpc832x_mds.dts
arch/powerpc/boot/dts/mpc832x_rdb.dts
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/boot/dts/mpc8349emitxgp.dts
arch/powerpc/boot/dts/mpc834x_mds.dts
arch/powerpc/boot/dts/mpc836x_mds.dts
arch/powerpc/boot/dts/mpc836x_rdk.dts
arch/powerpc/boot/dts/mpc8377_mds.dts
arch/powerpc/boot/dts/mpc8377_rdb.dts
arch/powerpc/boot/dts/mpc8378_mds.dts
arch/powerpc/boot/dts/mpc8378_rdb.dts
arch/powerpc/boot/dts/mpc8379_mds.dts
arch/powerpc/boot/dts/mpc8379_rdb.dts
arch/powerpc/boot/dts/mpc8536ds.dts
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/boot/dts/sbc8349.dts
arch/powerpc/boot/dts/sequoia.dts
arch/powerpc/boot/dts/yosemite.dts
arch/powerpc/boot/elf_util.c
arch/powerpc/boot/libfdt/Makefile.libfdt
arch/powerpc/boot/libfdt/fdt.c
arch/powerpc/boot/libfdt/fdt_ro.c
arch/powerpc/boot/libfdt/fdt_rw.c
arch/powerpc/boot/libfdt/fdt_strerror.c
arch/powerpc/boot/libfdt/fdt_sw.c
arch/powerpc/boot/libfdt/fdt_wip.c
arch/powerpc/boot/libfdt/libfdt.h
arch/powerpc/boot/libfdt/libfdt_internal.h
arch/powerpc/boot/libfdt_env.h
arch/powerpc/boot/wrapper
arch/powerpc/configs/44x/arches_defconfig [new file with mode: 0644]
arch/powerpc/configs/83xx/asp8347_defconfig
arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
arch/powerpc/configs/83xx/mpc832x_mds_defconfig
arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
arch/powerpc/configs/83xx/mpc834x_itx_defconfig
arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
arch/powerpc/configs/83xx/mpc834x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
arch/powerpc/configs/83xx/mpc837x_mds_defconfig
arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
arch/powerpc/configs/83xx/sbc834x_defconfig
arch/powerpc/configs/86xx/gef_sbc610_defconfig [new file with mode: 0644]
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig [moved from arch/powerpc/configs/mpc8610_hpcd_defconfig with 99% similarity]
arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig [moved from arch/powerpc/configs/mpc8641_hpcn_defconfig with 99% similarity]
arch/powerpc/configs/86xx/sbc8641d_defconfig [moved from arch/powerpc/configs/sbc8641d_defconfig with 99% similarity]
arch/powerpc/configs/ep8248e_defconfig
arch/powerpc/configs/mgcoge_defconfig [new file with mode: 0644]
arch/powerpc/configs/mgsuvd_defconfig [new file with mode: 0644]
arch/powerpc/configs/mpc8272_ads_defconfig
arch/powerpc/configs/mpc83xx_defconfig
arch/powerpc/configs/mpc86xx_defconfig [new file with mode: 0644]
arch/powerpc/configs/pq2fads_defconfig
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/dcr-regs.h
arch/powerpc/include/asm/device.h
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/elf.h
arch/powerpc/include/asm/exception.h
arch/powerpc/include/asm/fsl_lbc.h
arch/powerpc/include/asm/highmem.h
arch/powerpc/include/asm/io.h
arch/powerpc/include/asm/irq.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mman.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/mpic.h
arch/powerpc/include/asm/msi_bitmap.h [new file with mode: 0644]
arch/powerpc/include/asm/of_device.h
arch/powerpc/include/asm/of_platform.h
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/page_32.h
arch/powerpc/include/asm/pci.h
arch/powerpc/include/asm/pgtable-ppc32.h
arch/powerpc/include/asm/pgtable-ppc64.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/include/asm/sections.h
arch/powerpc/include/asm/sfp-machine.h [moved from arch/powerpc/math-emu/sfp-machine.h with 83% similarity]
arch/powerpc/include/asm/smp.h
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/tlbflush.h
arch/powerpc/include/asm/types.h
arch/powerpc/kernel/.gitignore [new file with mode: 0644]
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/cpu_setup_ppc970.S
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/dma-iommu.c [moved from arch/powerpc/kernel/dma_64.c with 53% similarity]
arch/powerpc/kernel/dma.c [new file with mode: 0644]
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/misc.S
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/of_device.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/reloc_64.S [new file with mode: 0644]
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/swsusp_asm64.S
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/vio.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/lib/copypage_64.S
arch/powerpc/lib/dma-noncoherent.c
arch/powerpc/math-emu/Makefile
arch/powerpc/math-emu/double.h [deleted file]
arch/powerpc/math-emu/fadd.c
arch/powerpc/math-emu/fadds.c
arch/powerpc/math-emu/fcmpo.c
arch/powerpc/math-emu/fcmpu.c
arch/powerpc/math-emu/fctiw.c
arch/powerpc/math-emu/fctiwz.c
arch/powerpc/math-emu/fdiv.c
arch/powerpc/math-emu/fdivs.c
arch/powerpc/math-emu/fmadd.c
arch/powerpc/math-emu/fmadds.c
arch/powerpc/math-emu/fmsub.c
arch/powerpc/math-emu/fmsubs.c
arch/powerpc/math-emu/fmul.c
arch/powerpc/math-emu/fmuls.c
arch/powerpc/math-emu/fnmadd.c
arch/powerpc/math-emu/fnmadds.c
arch/powerpc/math-emu/fnmsub.c
arch/powerpc/math-emu/fnmsubs.c
arch/powerpc/math-emu/frsp.c
arch/powerpc/math-emu/fsel.c
arch/powerpc/math-emu/fsqrt.c
arch/powerpc/math-emu/fsqrts.c
arch/powerpc/math-emu/fsub.c
arch/powerpc/math-emu/fsubs.c
arch/powerpc/math-emu/lfd.c
arch/powerpc/math-emu/lfs.c
arch/powerpc/math-emu/math.c
arch/powerpc/math-emu/mcrfs.c
arch/powerpc/math-emu/mffs.c
arch/powerpc/math-emu/mtfsb0.c
arch/powerpc/math-emu/mtfsb1.c
arch/powerpc/math-emu/mtfsf.c
arch/powerpc/math-emu/mtfsfi.c
arch/powerpc/math-emu/op-1.h [deleted file]
arch/powerpc/math-emu/op-2.h [deleted file]
arch/powerpc/math-emu/op-4.h [deleted file]
arch/powerpc/math-emu/op-common.h [deleted file]
arch/powerpc/math-emu/single.h [deleted file]
arch/powerpc/math-emu/soft-fp.h [deleted file]
arch/powerpc/math-emu/stfs.c
arch/powerpc/math-emu/types.c [deleted file]
arch/powerpc/math-emu/udivmodti4.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/gup.c
arch/powerpc/mm/hash_low_32.S
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/tlb_32.c
arch/powerpc/oprofile/cell/vma_map.c
arch/powerpc/oprofile/op_model_power4.c
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/44x/Makefile
arch/powerpc/platforms/44x/bamboo.c [deleted file]
arch/powerpc/platforms/44x/canyonlands.c [deleted file]
arch/powerpc/platforms/44x/katmai.c [deleted file]
arch/powerpc/platforms/44x/ppc44x_simple.c [new file with mode: 0644]
arch/powerpc/platforms/44x/rainier.c [deleted file]
arch/powerpc/platforms/44x/sequoia.c [deleted file]
arch/powerpc/platforms/44x/taishan.c [deleted file]
arch/powerpc/platforms/512x/Kconfig
arch/powerpc/platforms/512x/mpc5121_ads.c
arch/powerpc/platforms/52xx/mpc52xx_common.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/82xx/Kconfig
arch/powerpc/platforms/82xx/Makefile
arch/powerpc/platforms/82xx/mgcoge.c [new file with mode: 0644]
arch/powerpc/platforms/83xx/Kconfig
arch/powerpc/platforms/83xx/mpc837x_mds.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/sbc8560.c
arch/powerpc/platforms/86xx/Kconfig
arch/powerpc/platforms/86xx/Makefile
arch/powerpc/platforms/86xx/gef_pic.c [new file with mode: 0644]
arch/powerpc/platforms/86xx/gef_pic.h [new file with mode: 0644]
arch/powerpc/platforms/86xx/gef_sbc610.c [new file with mode: 0644]
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/86xx/sbc8641d.c
arch/powerpc/platforms/8xx/Kconfig
arch/powerpc/platforms/8xx/Makefile
arch/powerpc/platforms/8xx/mgsuvd.c [new file with mode: 0644]
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/chrp/time.c
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
arch/powerpc/platforms/iseries/exception.S
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/maple/time.c
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/powermac/time.c
arch/powerpc/platforms/ps3/system-bus.c
arch/powerpc/platforms/pseries/cmm.c
arch/powerpc/platforms/pseries/eeh_driver.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/platforms/pseries/reconfig.c
arch/powerpc/platforms/pseries/rtasd.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/platforms/pseries/xics.h
arch/powerpc/sysdev/Kconfig
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/cpm1.c
arch/powerpc/sysdev/fsl_lbc.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_msi.h
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/fsl_soc.h
arch/powerpc/sysdev/mpc8xxx_gpio.c [new file with mode: 0644]
arch/powerpc/sysdev/mpic.h
arch/powerpc/sysdev/mpic_msi.c
arch/powerpc/sysdev/mpic_pasemi_msi.c
arch/powerpc/sysdev/mpic_u3msi.c
arch/powerpc/sysdev/msi_bitmap.c [new file with mode: 0644]
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/qe_lib/Kconfig
arch/s390/include/asm/elf.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_linux.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/syscalls.S
arch/sh/include/asm/elf.h
arch/sparc/include/asm/elf_32.h
arch/sparc/include/asm/elf_64.h
arch/sparc64/kernel/iommu.c
arch/sparc64/kernel/iommu_common.h
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/sparc64/kernel/us3_cpufreq.c
arch/um/kernel/exec.c
arch/um/os-Linux/Makefile
arch/um/os-Linux/tty_log.c [deleted file]
arch/x86/Kconfig
arch/x86/boot/video-vesa.c
arch/x86/ia32/ia32entry.S
arch/x86/ia32/sys_ia32.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/dumpstack_32.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/msr.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/x86.c
arch/x86/mm/fault.c
block/bsg.c
drivers/ata/pata_of_platform.c
drivers/base/Kconfig
drivers/base/bus.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/firmware_class.c
drivers/base/platform.c
drivers/base/power/main.c
drivers/block/aoe/aoechr.c
drivers/block/floppy.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/pktcdvd.c
drivers/block/viodasd.c
drivers/char/Kconfig
drivers/char/agp/amd-k7-agp.c
drivers/char/agp/intel-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/applicom.c
drivers/char/bsr.c
drivers/char/ds1286.c
drivers/char/dsp56k.c
drivers/char/hvc_console.c
drivers/char/hw_random/omap-rng.c
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/istallion.c
drivers/char/keyboard.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/moxa.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/ppdev.c
drivers/char/random.c
drivers/char/raw.c
drivers/char/rtc.c
drivers/char/snsc.c
drivers/char/stallion.c
drivers/char/sysrq.c
drivers/char/tpm/tpm.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/viotape.c
drivers/char/vt.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/dca/dca-sysfs.c
drivers/edac/i5000_edac.c
drivers/edac/i82443bxgx_edac.c
drivers/edac/mpc85xx_edac.c
drivers/firewire/fw-card.c
drivers/firewire/fw-cdev.c
drivers/firewire/fw-device.c
drivers/firewire/fw-sbp2.c
drivers/firewire/fw-transaction.c
drivers/firewire/fw-transaction.h
drivers/firmware/iscsi_ibft.c
drivers/gpio/gpiolib.c
drivers/gpio/max7301.c
drivers/gpio/max732x.c
drivers/gpio/mcp23s08.c
drivers/gpio/pca953x.c
drivers/gpio/pcf857x.c
drivers/gpu/drm/i915/i915_dma.c
drivers/hid/Kconfig
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hidraw.c
drivers/hwmon/ams/ams.h
drivers/hwmon/hwmon.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/chips/Kconfig
drivers/i2c/chips/Makefile
drivers/i2c/chips/mcu_mpc8349emitx.c [new file with mode: 0644]
drivers/i2c/i2c-dev.c
drivers/ide/Kconfig
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ieee1394/csr1212.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/eth1394.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.h
drivers/ieee1394/raw1394-private.h
drivers/ieee1394/raw1394.c
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.h
drivers/ieee1394/video1394.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/input/gameport/gameport.c
drivers/input/joystick/a3d.c
drivers/input/joystick/adi.c
drivers/input/joystick/analog.c
drivers/input/joystick/cobra.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/interact.c
drivers/input/joystick/joydump.c
drivers/input/joystick/sidewinder.c
drivers/input/joystick/tmdc.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/omap-keypad.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ati_remote2.c
drivers/input/misc/cm109.c [new file with mode: 0644]
drivers/input/misc/wistron_btns.c
drivers/input/misc/yealink.c
drivers/input/mouse/Kconfig
drivers/input/mouse/Makefile
drivers/input/mouse/alps.c
drivers/input/mouse/appletouch.c
drivers/input/mouse/hgpk.c [new file with mode: 0644]
drivers/input/mouse/hgpk.h [new file with mode: 0644]
drivers/input/mouse/logips2pp.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/trackpoint.c
drivers/input/serio/i8042-io.h
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/serio_raw.c
drivers/input/tablet/aiptek.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/atmel_tsadcc.c
drivers/input/touchscreen/mainstone-wm97xx.c
drivers/input/touchscreen/wm9705.c
drivers/input/touchscreen/wm9712.c
drivers/input/touchscreen/wm9713.c
drivers/input/touchscreen/wm97xx-core.c
drivers/isdn/capi/capi.c
drivers/leds/led-class.c
drivers/macintosh/adb.c
drivers/md/faulty.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6.h
drivers/media/dvb/dvb-core/dvbdev.c
drivers/media/video/cpia.c
drivers/media/video/usbvision/usbvision-core.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l1-compat.c
drivers/media/video/v4l2-common.c
drivers/media/video/vino.c
drivers/media/video/w9968cf.c
drivers/message/i2o/Makefile
drivers/message/i2o/device.c
drivers/message/i2o/exec-osm.c
drivers/message/i2o/i2o_config.c
drivers/message/i2o/iop.c
drivers/message/i2o/memory.c [new file with mode: 0644]
drivers/message/i2o/pci.c
drivers/misc/Kconfig
drivers/misc/hp-wmi.c
drivers/misc/phantom.c
drivers/misc/sgi-gru/gru.h
drivers/misc/sgi-gru/gru_instructions.h
drivers/misc/sgi-gru/grufault.c
drivers/misc/sgi-gru/grufile.c
drivers/misc/sgi-gru/gruhandles.h
drivers/misc/sgi-gru/grukservices.c
drivers/misc/sgi-gru/grumain.c
drivers/mmc/host/omap.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/ams-delta.c
drivers/net/3c509.c
drivers/net/cs89x0.c
drivers/net/ibm_newemac/Kconfig
drivers/net/ibm_newemac/core.c
drivers/net/ibm_newemac/core.h
drivers/net/ibm_newemac/mal.c
drivers/net/ibm_newemac/mal.h
drivers/net/ibm_newemac/phy.c
drivers/net/ibm_newemac/phy.h
drivers/net/irda/sir_dongle.c
drivers/net/phy/phy_device.c
drivers/net/ppp_generic.c
drivers/net/pppox.c
drivers/net/wan/cosa.c
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/orinoco_cs.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/spectrum_cs.c
drivers/net/xen-netfront.c
drivers/nubus/nubus.c
drivers/of/base.c
drivers/of/gpio.c
drivers/parport/ChangeLog
drivers/parport/ieee1284.c
drivers/parport/probe.c
drivers/parport/share.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/probe.c
drivers/pcmcia/Makefile
drivers/pnp/base.h
drivers/pnp/core.c
drivers/pnp/driver.c
drivers/pnp/interface.c
drivers/pnp/isapnp/core.c
drivers/pnp/pnpbios/core.c
drivers/pnp/quirks.c
drivers/pnp/resource.c
drivers/power/olpc_battery.c
drivers/power/power_supply_core.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-ds1286.c [new file with mode: 0644]
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-ds3234.c [new file with mode: 0644]
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-m48t35.c [new file with mode: 0644]
drivers/rtc/rtc-max6900.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-pl030.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-stk17ta8.c
drivers/s390/char/raw3270.c
drivers/s390/char/tape_class.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/vmur.c
drivers/s390/net/ctcm_mpc.c
drivers/scsi/ch.c
drivers/scsi/dpt_i2o.c
drivers/scsi/osst.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/serial/8250.c
drivers/serial/Kconfig
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/cpm_uart/cpm_uart_cpm1.c
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/mpc52xx_uart.c
drivers/serial/s3c2400.c
drivers/serial/s3c2410.c
drivers/serial/s3c2412.c
drivers/serial/s3c2440.c
drivers/serial/samsung.c
drivers/serial/ucc_uart.c
drivers/spi/mpc52xx_psc_spi.c
drivers/spi/omap2_mcspi.c
drivers/spi/omap_uwire.c
drivers/spi/orion_spi.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi.c
drivers/spi/spi_s3c24xx.c
drivers/spi/spidev.c
drivers/telephony/ixj.c
drivers/uio/Kconfig
drivers/uio/Makefile
drivers/uio/uio.c
drivers/uio/uio_pdrv.c
drivers/uio/uio_sercos3.c [new file with mode: 0644]
drivers/usb/core/devio.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/gadget/Makefile
drivers/usb/gadget/cdc2.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/f_ecm.c
drivers/usb/gadget/f_loopback.c
drivers/usb/gadget/f_subset.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/printer.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/serial.c
drivers/usb/gadget/u_ether.c
drivers/usb/gadget/zero.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/uhci-q.c
drivers/usb/misc/phidgetkit.c
drivers/usb/misc/phidgetmotorcontrol.c
drivers/usb/misc/phidgetservo.c
drivers/usb/mon/mon_bin.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/atmel_lcdfb.c
drivers/video/aty/radeon_accel.c
drivers/video/aty/radeon_backlight.c
drivers/video/aty/radeon_base.c
drivers/video/aty/radeon_i2c.c
drivers/video/aty/radeon_pm.c
drivers/video/aty/radeonfb.h
drivers/video/carminefb.c
drivers/video/cirrusfb.c
drivers/video/console/fbcon.c
drivers/video/console/vgacon.c
drivers/video/display/display-sysfs.c
drivers/video/efifb.c
drivers/video/fbmem.c
drivers/video/fbmon.c
drivers/video/imacfb.c
drivers/video/intelfb/intelfb.h
drivers/video/intelfb/intelfb_i2c.c
drivers/video/intelfb/intelfbdrv.c
drivers/video/intelfb/intelfbhw.c
drivers/video/matrox/matroxfb_base.c
drivers/video/metronomefb.c
drivers/video/neofb.c
drivers/video/omap/dispc.c
drivers/video/omap/dispc.h
drivers/video/omap/lcd_h4.c
drivers/video/omap/lcd_inn1610.c
drivers/video/omap/lcd_osk.c
drivers/video/omap/lcd_sx1.c
drivers/video/omap/lcdc.c
drivers/video/omap/lcdc.h
drivers/video/omap/omapfb_main.c
drivers/video/omap/rfbi.c
drivers/video/omap/sossi.c
drivers/video/s1d13xxxfb.c
drivers/video/tdfxfb.c
drivers/video/tmiofb.c [new file with mode: 0644]
drivers/video/uvesafb.c
drivers/video/vga16fb.c
drivers/video/via/Makefile [new file with mode: 0644]
drivers/video/via/accel.c [new file with mode: 0644]
drivers/video/via/accel.h [new file with mode: 0644]
drivers/video/via/chip.h [new file with mode: 0644]
drivers/video/via/debug.h [new file with mode: 0644]
drivers/video/via/dvi.c [new file with mode: 0644]
drivers/video/via/dvi.h [new file with mode: 0644]
drivers/video/via/global.c [new file with mode: 0644]
drivers/video/via/global.h [new file with mode: 0644]
drivers/video/via/hw.c [new file with mode: 0644]
drivers/video/via/hw.h [new file with mode: 0644]
drivers/video/via/iface.c [new file with mode: 0644]
drivers/video/via/iface.h [new file with mode: 0644]
drivers/video/via/ioctl.c [new file with mode: 0644]
drivers/video/via/ioctl.h [new file with mode: 0644]
drivers/video/via/lcd.c [new file with mode: 0644]
drivers/video/via/lcd.h [new file with mode: 0644]
drivers/video/via/lcdtbl.h [new file with mode: 0644]
drivers/video/via/share.h [new file with mode: 0644]
drivers/video/via/tbl1636.c [new file with mode: 0644]
drivers/video/via/tbl1636.h [new file with mode: 0644]
drivers/video/via/tblDPASetting.c [new file with mode: 0644]
drivers/video/via/tblDPASetting.h [new file with mode: 0644]
drivers/video/via/via_i2c.c [new file with mode: 0644]
drivers/video/via/via_i2c.h [new file with mode: 0644]
drivers/video/via/via_utility.c [new file with mode: 0644]
drivers/video/via/via_utility.h [new file with mode: 0644]
drivers/video/via/viafbdev.c [new file with mode: 0644]
drivers/video/via/viafbdev.h [new file with mode: 0644]
drivers/video/via/viamode.c [new file with mode: 0644]
drivers/video/via/viamode.h [new file with mode: 0644]
drivers/video/via/vt1636.c [new file with mode: 0644]
drivers/video/via/vt1636.h [new file with mode: 0644]
drivers/w1/masters/ds1wm.c
drivers/w1/masters/ds2490.c
drivers/w1/slaves/w1_ds2431.c [new file with mode: 0644]
drivers/w1/slaves/w1_therm.c
drivers/w1/w1.c
drivers/w1/w1.h
drivers/w1/w1_family.c
drivers/w1/w1_family.h
drivers/w1/w1_int.c
drivers/w1/w1_io.c
fs/Kconfig.binfmt
fs/Makefile
fs/afs/file.c
fs/afs/internal.h
fs/afs/write.c
fs/autofs4/Makefile
fs/autofs4/autofs_i.h
fs/autofs4/dev-ioctl.c [new file with mode: 0644]
fs/autofs4/expire.c
fs/autofs4/init.c
fs/autofs4/inode.c
fs/autofs4/waitq.c
fs/befs/befs_fs_types.h
fs/befs/linuxvfs.c
fs/befs/super.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_em86.c
fs/binfmt_flat.c
fs/binfmt_misc.c
fs/binfmt_script.c
fs/binfmt_som.c
fs/char_dev.c
fs/coda/psdev.c
fs/compat.c
fs/direct-io.c
fs/dquot.c
fs/ecryptfs/Makefile
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/messaging.c
fs/ecryptfs/mmap.c
fs/ecryptfs/netlink.c [deleted file]
fs/eventpoll.c
fs/exec.c
fs/ext2/balloc.c
fs/ext2/dir.c
fs/fs-writeback.c
fs/hfs/catalog.c
fs/hfsplus/bitmap.c
fs/hfsplus/catalog.c
fs/hfsplus/super.c
fs/mpage.c
fs/nls/nls_base.c
fs/ocfs2/xattr.c
fs/partitions/acorn.c
fs/partitions/check.c
fs/proc/proc_misc.c
fs/reiserfs/procfs.c
fs/reiserfs/xattr.c
fs/sysfs/bin.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/mount.c
fs/sysfs/sysfs.h
fs/xfs/linux-2.6/xfs_super.c
include/acpi/acmacros.h
include/acpi/platform/acgcc.h
include/asm-cris/elf.h
include/asm-frv/elf.h
include/asm-frv/unaligned.h
include/asm-generic/bug.h
include/asm-generic/gpio.h
include/asm-generic/vmlinux.lds.h
include/asm-h8300/timer.h [new file with mode: 0644]
include/asm-m32r/elf.h
include/asm-m68k/elf.h
include/asm-mn10300/elf.h
include/asm-parisc/elf.h
include/asm-um/elf-i386.h
include/asm-um/elf-ppc.h
include/asm-um/elf-x86_64.h
include/asm-x86/elf.h
include/asm-x86/es7000/apic.h
include/asm-x86/iommu.h
include/asm-x86/pgtable.h
include/asm-x86/summit/apic.h
include/asm-xtensa/elf.h
include/linux/Kbuild
include/linux/aio.h
include/linux/auto_dev-ioctl.h [new file with mode: 0644]
include/linux/auto_fs4.h
include/linux/binfmts.h
include/linux/cgroup.h
include/linux/clk.h
include/linux/compat.h
include/linux/device.h
include/linux/ds1286.h
include/linux/dynamic_printk.h [new file with mode: 0644]
include/linux/ext2_fs.h
include/linux/ext3_fs.h
include/linux/ext3_jbd.h
include/linux/firewire-cdev.h
include/linux/gameport.h
include/linux/gpio.h
include/linux/i2o.h
include/linux/icmpv6.h
include/linux/init.h
include/linux/input.h
include/linux/iommu-helper.h
include/linux/ioport.h
include/linux/jbd.h
include/linux/jbd2.h
include/linux/journal-head.h
include/linux/kallsyms.h
include/linux/kernel.h
include/linux/kmod.h
include/linux/map_to_7segment.h [moved from drivers/input/misc/map_to_7segment.h with 98% similarity]
include/linux/mfd/tmio.h
include/linux/mod_devicetable.h
include/linux/module.h
include/linux/mount.h
include/linux/netfilter/nfnetlink.h
include/linux/of.h
include/linux/parport.h
include/linux/pci_ids.h
include/linux/pid_namespace.h
include/linux/platform_device.h
include/linux/pm.h
include/linux/pnp.h
include/linux/proc_fs.h
include/linux/profile.h
include/linux/quota.h
include/linux/quotaops.h
include/linux/raid/linear.h
include/linux/raid/md.h
include/linux/reiserfs_fs.h
include/linux/rtmutex.h
include/linux/spi/orion_spi.h
include/linux/swiotlb.h [new file with mode: 0644]
include/linux/sysctl.h
include/linux/sysfs.h
include/linux/task_io_accounting.h
include/linux/telephony.h
include/linux/time.h
include/linux/wait.h
include/math-emu/op-2.h
include/math-emu/op-common.h
include/math-emu/soft-fp.h
include/media/saa7146.h
include/net/9p/9p.h
include/net/bluetooth/bluetooth.h
include/net/ieee80211.h
include/net/ip.h
include/net/ip_vs.h
include/net/irda/irda.h
include/net/mac80211.h
include/net/ndisc.h
include/net/netfilter/nf_nat_core.h
include/net/sctp/sctp.h
include/video/cyblafb.h
include/video/neomagic.h
include/video/radeon.h
include/video/s1d13xxxfb.h
init/Kconfig
init/do_mounts_md.c
init/do_mounts_rd.c
init/initramfs.c
ipc/ipc_sysctl.c
ipc/sem.c
kernel/cgroup.c
kernel/compat.c
kernel/dma.c
kernel/exit.c
kernel/kallsyms.c
kernel/kmod.c
kernel/kprobes.c
kernel/ksysfs.c
kernel/module.c
kernel/panic.c
kernel/power/disk.c
kernel/power/main.c
kernel/power/user.c
kernel/printk.c
kernel/profile.c
kernel/resource.c
kernel/softlockup.c
kernel/sys.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/time/Kconfig
kernel/utsname_sysctl.c
kernel/wait.c
kernel/workqueue.c
lib/Kconfig
lib/Kconfig.debug
lib/Makefile
lib/dynamic_printk.c [new file with mode: 0644]
lib/iommu-helper.c
lib/kobject.c
lib/vsprintf.c
mm/Kconfig
mm/bootmem.c
mm/fadvise.c
mm/filemap.c
mm/hugetlb.c
mm/page-writeback.c
mm/page_alloc.c
mm/pdflush.c
mm/readahead.c
mm/truncate.c
net/802/fc.c
net/bridge/netfilter/Kconfig
net/core/net_namespace.c
net/decnet/dn_dev.c
net/decnet/sysctl_net_decnet.c
net/ipv4/devinet.c
net/ipv4/netfilter/nf_defrag_ipv4.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/route.c
net/ipv4/sysctl_net_ipv4.c
net/ipv6/addrconf.c
net/ipv6/ndisc.c
net/ipv6/netfilter.c
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_sta.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/util.c
net/mac80211/wext.c
net/netfilter/nf_conntrack_acct.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nfnetlink.c
net/wireless/core.c
scripts/Makefile.lib
scripts/basic/Makefile
scripts/basic/hash.c [new file with mode: 0644]
scripts/checkpatch.pl
sound/aoa/soundbus/soundbus.h
sound/core/init.c
sound/core/sound.c
sound/oss/soundcard.c
sound/sound_core.c

index 4382778001039c7fc6595f7659895a7301533ba8..7286ad090db7b81242b223786d897a4518db2a1d 100644 (file)
@@ -21,6 +21,9 @@ Changes
        - list of changes that break older software packages.
 CodingStyle
        - how the boss likes the C code in the kernel to look.
+development-process/
+       - An extended tutorial on how to work with the kernel development
+         process.
 DMA-API.txt
        - DMA API, pci_ API & extensions for non-consistent memory machines.
 DMA-ISA-LPC.txt
diff --git a/Documentation/ABI/testing/sysfs-profiling b/Documentation/ABI/testing/sysfs-profiling
new file mode 100644 (file)
index 0000000..b02d8b8
--- /dev/null
@@ -0,0 +1,13 @@
+What:          /sys/kernel/profile
+Date:          September 2008
+Contact:       Dave Hansen <dave@linux.vnet.ibm.com>
+Description:
+               /sys/kernel/profile is the runtime equivalent
+               of the boot-time profile= option.
+
+               You can get the same effect running:
+
+                       echo 2 > /sys/kernel/profile
+
+               as you would by issuing profile=2 on the boot
+               command line.
index 1615350b7b53b4b681ed187e176e896ca0b0845e..fabc06466b93d69a842af47403e7b5f9c5977502 100644 (file)
@@ -6,7 +6,7 @@
 # To add a new book the only step required is to add the book to the
 # list of DOCBOOKS.
 
-DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
+DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml \
            kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
            procfs-guide.xml writing_usb_driver.xml networking.xml \
            kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
index 8a5dc6e021ffa8b16b6dc2f997e115e77b1aaf70..9eba4b7af73de9dd5d6d83086c374c07efb5a1bc 100644 (file)
        <othername>(J.A.K.)</othername>
        <surname>Mouw</surname>
        <affiliation>
-         <orgname>Delft University of Technology</orgname>
-         <orgdiv>Faculty of Information Technology and Systems</orgdiv>
          <address>
-            <email>J.A.K.Mouw@its.tudelft.nl</email>
-            <pob>PO BOX 5031</pob>
-            <postcode>2600 GA</postcode>
-            <city>Delft</city>
-            <country>The Netherlands</country>
+            <email>mouw@nl.linux.org</email>
           </address>
        </affiliation>
       </author>
+      <othercredit>
+       <contrib>
+       This software and documentation were written while working on the
+       LART computing board
+       (<ulink url="http://www.lartmaker.nl/">http://www.lartmaker.nl/</ulink>),
+       which was sponsored by the Delt University of Technology projects
+       Mobile Multi-media Communications and Ubiquitous Communications.
+       </contrib>
+      </othercredit>
     </authorgroup>
 
     <revhistory>
       proofreading.
     </para>
 
-    <para>
-      This documentation was written while working on the LART
-      computing board (<ulink
-      url="http://www.lart.tudelft.nl/">http://www.lart.tudelft.nl/</ulink>),
-      which is sponsored by the Mobile Multi-media Communications
-      (<ulink
-      url="http://www.mmc.tudelft.nl/">http://www.mmc.tudelft.nl/</ulink>)
-      and Ubiquitous Communications (<ulink
-      url="http://www.ubicom.tudelft.nl/">http://www.ubicom.tudelft.nl/</ulink>)
-      projects.
-    </para>
-
     <para>
       Erik
     </para>
index 2f3de0fb83651779e3c849c8ec2c9706c13a2ac4..8c6396e4bf311901a19fd717500c422eeba4869a 100644 (file)
@@ -1,28 +1,16 @@
 /*
  * procfs_example.c: an example proc interface
  *
- * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ * Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org)
  *
  * This file accompanies the procfs-guide in the Linux kernel
  * source. Its main use is to demonstrate the concepts and
  * functions described in the guide.
  *
  * This software has been developed while working on the LART
- * computing board (http://www.lart.tudelft.nl/), which is
- * sponsored by the Mobile Multi-media Communications
- * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications 
- * (http://www.ubicom.tudelft.nl/) projects.
- *
- * The author can be reached at:
- *
- *  Erik Mouw
- *  Information and Communication Theory Group
- *  Faculty of Information Technology and Systems
- *  Delft University of Technology
- *  P.O. Box 5031
- *  2600 GA Delft
- *  The Netherlands
- *
+ * computing board (http://www.lartmaker.nl), which was sponsored
+ * by the Delt University of Technology projects Mobile Multi-media
+ * Communications and Ubiquitous Communications.
  *
  * This program is free software; you can redistribute
  * it and/or modify it under the terms of the GNU General
diff --git a/Documentation/DocBook/videobook.tmpl b/Documentation/DocBook/videobook.tmpl
deleted file mode 100644 (file)
index 0bc2594..0000000
+++ /dev/null
@@ -1,1654 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-       "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="V4LGuide">
- <bookinfo>
-  <title>Video4Linux Programming</title>
-  
-  <authorgroup>
-   <author>
-    <firstname>Alan</firstname>
-    <surname>Cox</surname>
-    <affiliation>
-     <address>
-      <email>alan@redhat.com</email>
-     </address>
-    </affiliation>
-   </author>
-  </authorgroup>
-
-  <copyright>
-   <year>2000</year>
-   <holder>Alan Cox</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-     This documentation 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.
-   </para>
-      
-   <para>
-     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.
-   </para>
-      
-   <para>
-     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
-   </para>
-      
-   <para>
-     For more details see the file COPYING in the source
-     distribution of Linux.
-   </para>
-  </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
-  <chapter id="intro">
-      <title>Introduction</title>
-  <para>
-        Parts of this document first appeared in Linux Magazine under a
-        ninety day exclusivity.
-  </para>
-  <para>
-        Video4Linux is intended to provide a common programming interface
-        for the many TV and capture cards now on the market, as well as
-        parallel port and USB video cameras. Radio, teletext decoders and
-        vertical blanking data interfaces are also provided.
-  </para>
-  </chapter>
-  <chapter id="radio">
-        <title>Radio Devices</title>
-  <para>
-        There are a wide variety of radio interfaces available for PC's, and these
-        are generally very simple to program. The biggest problem with supporting
-        such devices is normally extracting documentation from the vendor.
-  </para>
-  <para>
-        The radio interface supports a simple set of control ioctls standardised
-        across all radio and tv interfaces. It does not support read or write, which
-        are used for video streams. The reason radio cards do not allow you to read
-        the audio stream into an application is that without exception they provide
-        a connection on to a soundcard. Soundcards can be used to read the radio
-        data just fine. 
-  </para>
-  <sect1 id="registerradio">
-  <title>Registering Radio Devices</title>
-  <para>
-        The Video4linux core provides an interface for registering devices. The
-        first step in writing our radio card driver is to register it.
-  </para>
-  <programlisting>
-
-
-static struct video_device my_radio
-{
-        "My radio",
-        VID_TYPE_TUNER,
-        radio_open.
-        radio_close,
-        NULL,                /* no read */
-        NULL,                 /* no write */
-        NULL,                /* no poll */
-        radio_ioctl,
-        NULL,                /* no special init function */
-        NULL                /* no private data */
-};
-
-
-  </programlisting>
-  <para>
-        This declares our video4linux device driver interface. The VID_TYPE_ value
-        defines what kind of an interface we are, and defines basic capabilities.
-  </para>
-  <para>
-        The only defined value relevant for a radio card is VID_TYPE_TUNER which
-        indicates that the device can be tuned. Clearly our radio is going to have some
-        way to change channel so it is tuneable.
-  </para>
-  <para>
-        We declare an open and close routine, but we do not need read or write,
-        which are used to read and write video data to or from the card itself. As
-        we have no read or write there is no poll function.
-  </para>
-  <para>
-        The private initialise function is run when the device is registered. In
-        this driver we've already done all the work needed. The final pointer is a
-        private data pointer that can be used by the device driver to attach and
-        retrieve private data structures. We set this field "priv" to NULL for
-        the moment.
-  </para>
-  <para>
-        Having the structure defined is all very well but we now need to register it
-        with the kernel. 
-  </para>
-  <programlisting>
-
-
-static int io = 0x320;
-
-int __init myradio_init(struct video_init *v)
-{
-        if(!request_region(io, MY_IO_SIZE, "myradio"))
-        {
-                printk(KERN_ERR 
-                    "myradio: port 0x%03X is in use.\n", io);
-                return -EBUSY;
-        }
-
-        if(video_device_register(&amp;my_radio, VFL_TYPE_RADIO)==-1) {
-                release_region(io, MY_IO_SIZE);
-                return -EINVAL;
-        }              
-        return 0;
-}
-
-  </programlisting>
-  <para>
-        The first stage of the initialisation, as is normally the case, is to check 
-        that the I/O space we are about to fiddle with doesn't belong to some other 
-        driver. If it is we leave well alone. If the user gives the address of the 
-        wrong device then we will spot this. These policies will generally avoid 
-        crashing the machine.
-  </para>
-  <para>
-        Now we ask the Video4Linux layer to register the device for us. We hand it
-        our carefully designed video_device structure and also tell it which group
-        of devices we want it registered with. In this case VFL_TYPE_RADIO.
-  </para>
-  <para>
-        The types available are
-  </para>
-   <table frame="all" id="Device_Types"><title>Device Types</title>
-   <tgroup cols="3" align="left">
-   <tbody>
-   <row>
-        <entry>VFL_TYPE_RADIO</entry><entry>/dev/radio{n}</entry><entry>
-
-        Radio devices are assigned in this block. As with all of these
-        selections the actual number assignment is done by the video layer
-        accordijng to what is free.</entry>
-       </row><row>
-        <entry>VFL_TYPE_GRABBER</entry><entry>/dev/video{n}</entry><entry>
-        Video capture devices and also -- counter-intuitively for the name --
-        hardware video playback devices such as MPEG2 cards.</entry>
-       </row><row>
-        <entry>VFL_TYPE_VBI</entry><entry>/dev/vbi{n}</entry><entry>
-        The VBI devices capture the hidden lines on a television picture
-        that carry further information like closed caption data, teletext
-        (primarily in Europe) and now Intercast and the ATVEC internet
-        television encodings.</entry>
-       </row><row>
-        <entry>VFL_TYPE_VTX</entry><entry>/dev/vtx[n}</entry><entry>
-        VTX is 'Videotext' also known as 'Teletext'. This is a system for
-        sending numbered, 40x25, mostly textual page images over the hidden
-        lines. Unlike the /dev/vbi interfaces, this is for 'smart' decoder 
-        chips. (The use of the word smart here has to be taken in context,
-        the smartest teletext chips are fairly dumb pieces of technology).
-       </entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-  <para>
-        We are most definitely a radio.
-  </para>
-  <para>
-        Finally we allocate our I/O space so that nobody treads on us and return 0
-        to signify general happiness with the state of the universe.
-  </para>
-  </sect1>
-  <sect1 id="openradio">
-  <title>Opening And Closing The Radio</title>
-
-  <para>
-        The functions we declared in our video_device are mostly very simple.
-        Firstly we can drop in what is basically standard code for open and close. 
-  </para>
-  <programlisting>
-
-
-static int users = 0;
-
-static int radio_open(struct video_device *dev, int flags)
-{
-        if(users)
-                return -EBUSY;
-        users++;
-        return 0;
-}
-
-  </programlisting>
-  <para>
-        At open time we need to do nothing but check if someone else is also using
-        the radio card. If nobody is using it we make a note that we are using it,
-        then we ensure that nobody unloads our driver on us.
-  </para>
-  <programlisting>
-
-
-static int radio_close(struct video_device *dev)
-{
-        users--;
-}
-
-  </programlisting>
-  <para>
-        At close time we simply need to reduce the user count and allow the module
-        to become unloadable.
-  </para>
-  <para>
-        If you are sharp you will have noticed neither the open nor the close
-        routines attempt to reset or change the radio settings. This is intentional.
-        It allows an application to set up the radio and exit. It avoids a user
-        having to leave an application running all the time just to listen to the
-        radio. 
-  </para>
-  </sect1>
-  <sect1 id="ioctlradio">
-  <title>The Ioctl Interface</title>
-  <para>
-        This leaves the ioctl routine, without which the driver will not be
-        terribly useful to anyone.
-  </para>
-  <programlisting>
-
-
-static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
-        switch(cmd)
-        {
-                case VIDIOCGCAP:
-                {
-                        struct video_capability v;
-                        v.type = VID_TYPE_TUNER;
-                        v.channels = 1;
-                        v.audios = 1;
-                        v.maxwidth = 0;
-                        v.minwidth = 0;
-                        v.maxheight = 0;
-                        v.minheight = 0;
-                        strcpy(v.name, "My Radio");
-                        if(copy_to_user(arg, &amp;v, sizeof(v)))
-                                return -EFAULT;
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        VIDIOCGCAP is the first ioctl all video4linux devices must support. It
-        allows the applications to find out what sort of a card they have found and
-        to figure out what they want to do about it. The fields in the structure are
-  </para>
-   <table frame="all" id="video_capability_fields"><title>struct video_capability fields</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-        <entry>name</entry><entry>The device text name. This is intended for the user.</entry>
-       </row><row>
-        <entry>channels</entry><entry>The number of different channels you can tune on
-                        this card. It could even by zero for a card that has
-                        no tuning capability. For our simple FM radio it is 1. 
-                        An AM/FM radio would report 2.</entry>
-       </row><row>
-        <entry>audios</entry><entry>The number of audio inputs on this device. For our
-                        radio there is only one audio input.</entry>
-       </row><row>
-        <entry>minwidth,minheight</entry><entry>The smallest size the card is capable of capturing
-                       images in. We set these to zero. Radios do not
-                        capture pictures</entry>
-       </row><row>
-        <entry>maxwidth,maxheight</entry><entry>The largest image size the card is capable of
-                                      capturing. For our radio we report 0.
-                               </entry>
-       </row><row>
-        <entry>type</entry><entry>This reports the capabilities of the device, and
-                        matches the field we filled in in the struct
-                        video_device when registering.</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-  <para>
-        Having filled in the fields, we use copy_to_user to copy the structure into
-        the users buffer. If the copy fails we return an EFAULT to the application
-        so that it knows it tried to feed us garbage.
-  </para>
-  <para>
-        The next pair of ioctl operations select which tuner is to be used and let
-        the application find the tuner properties. We have only a single FM band
-        tuner in our example device.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCGTUNER:
-                {
-                        struct video_tuner v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v))!=0)
-                                return -EFAULT;
-                        if(v.tuner)
-                                return -EINVAL;
-                        v.rangelow=(87*16000);
-                        v.rangehigh=(108*16000);
-                        v.flags = VIDEO_TUNER_LOW;
-                        v.mode = VIDEO_MODE_AUTO;
-                        v.signal = 0xFFFF;
-                        strcpy(v.name, "FM");
-                        if(copy_to_user(&amp;v, arg, sizeof(v))!=0)
-                                return -EFAULT;
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        The VIDIOCGTUNER ioctl allows applications to query a tuner. The application
-        sets the tuner field to the tuner number it wishes to query. The query does
-        not change the tuner that is being used, it merely enquires about the tuner
-        in question.
-  </para>
-  <para>
-        We have exactly one tuner so after copying the user buffer to our temporary
-        structure we complain if they asked for a tuner other than tuner 0. 
-  </para>
-  <para>
-        The video_tuner structure has the following fields
-  </para>
-   <table frame="all" id="video_tuner_fields"><title>struct video_tuner fields</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-        <entry>int tuner</entry><entry>The number of the tuner in question</entry>
-   </row><row>
-        <entry>char name[32]</entry><entry>A text description of this tuner. "FM" will do fine.
-                        This is intended for the application.</entry>
-   </row><row>
-        <entry>u32 flags</entry>
-        <entry>Tuner capability flags</entry>
-   </row>
-   <row>
-        <entry>u16 mode</entry><entry>The current reception mode</entry>
-
-   </row><row>
-        <entry>u16 signal</entry><entry>The signal strength scaled between 0 and 65535. If
-                        a device cannot tell the signal strength it should
-                        report 65535. Many simple cards contain only a 
-                        signal/no signal bit. Such cards will report either
-                        0 or 65535.</entry>
-
-   </row><row>
-        <entry>u32 rangelow, rangehigh</entry><entry>
-                        The range of frequencies supported by the radio
-                        or TV. It is scaled according to the VIDEO_TUNER_LOW
-                        flag.</entry>
-
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-
-   <table frame="all" id="video_tuner_flags"><title>struct video_tuner flags</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-       <entry>VIDEO_TUNER_PAL</entry><entry>A PAL TV tuner</entry>
-       </row><row>
-        <entry>VIDEO_TUNER_NTSC</entry><entry>An NTSC (US) TV tuner</entry>
-       </row><row>
-        <entry>VIDEO_TUNER_SECAM</entry><entry>A SECAM (French) TV tuner</entry>
-       </row><row>
-        <entry>VIDEO_TUNER_LOW</entry><entry>
-             The tuner frequency is scaled in 1/16th of a KHz
-             steps. If not it is in 1/16th of a MHz steps
-       </entry>
-       </row><row>
-        <entry>VIDEO_TUNER_NORM</entry><entry>The tuner can set its format</entry>
-       </row><row>
-        <entry>VIDEO_TUNER_STEREO_ON</entry><entry>The tuner is currently receiving a stereo signal</entry>
-        </row>
-    </tbody>
-    </tgroup>
-    </table>
-
-   <table frame="all" id="video_tuner_modes"><title>struct video_tuner modes</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-                <entry>VIDEO_MODE_PAL</entry><entry>PAL Format</entry>
-   </row><row>
-                <entry>VIDEO_MODE_NTSC</entry><entry>NTSC Format (USA)</entry>
-   </row><row>
-                <entry>VIDEO_MODE_SECAM</entry><entry>French Format</entry>
-   </row><row>
-                <entry>VIDEO_MODE_AUTO</entry><entry>A device that does not need to do
-                                        TV format switching</entry>
-   </row>
-    </tbody>
-    </tgroup>
-    </table>
-  <para>
-        The settings for the radio card are thus fairly simple. We report that we
-        are a tuner called "FM" for FM radio. In order to get the best tuning
-        resolution we report VIDEO_TUNER_LOW and select tuning to 1/16th of KHz. Its
-        unlikely our card can do that resolution but it is a fair bet the card can
-        do better than 1/16th of a MHz. VIDEO_TUNER_LOW is appropriate to almost all
-        radio usage.
-  </para>
-  <para>
-        We report that the tuner automatically handles deciding what format it is
-        receiving - true enough as it only handles FM radio. Our example card is
-        also incapable of detecting stereo or signal strengths so it reports a
-        strength of 0xFFFF (maximum) and no stereo detected.
-  </para>
-  <para>
-        To finish off we set the range that can be tuned to be 87-108Mhz, the normal
-        FM broadcast radio range. It is important to find out what the card is
-        actually capable of tuning. It is easy enough to simply use the FM broadcast
-        range. Unfortunately if you do this you will discover the FM broadcast
-        ranges in the USA, Europe and Japan are all subtly different and some users
-        cannot receive all the stations they wish.
-  </para>
-  <para>
-        The application also needs to be able to set the tuner it wishes to use. In
-        our case, with a single tuner this is rather simple to arrange.
-  </para>
-  <programlisting>
-
-                case VIDIOCSTUNER:
-                {
-                        struct video_tuner v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.tuner != 0)
-                                return -EINVAL;
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        We copy the user supplied structure into kernel memory so we can examine it. 
-        If the user has selected a tuner other than zero we reject the request. If 
-        they wanted tuner 0 then, surprisingly enough, that is the current tuner already.
-  </para>
-  <para>
-        The next two ioctls we need to provide are to get and set the frequency of
-        the radio. These both use an unsigned long argument which is the frequency.
-        The scale of the frequency depends on the VIDEO_TUNER_LOW flag as I
-        mentioned earlier on. Since we have VIDEO_TUNER_LOW set this will be in
-        1/16ths of a KHz.
-  </para>
-  <programlisting>
-
-static unsigned long current_freq;
-
-
-
-                case VIDIOCGFREQ:
-                        if(copy_to_user(arg, &amp;current_freq, 
-                                sizeof(unsigned long))
-                                return -EFAULT;
-                        return 0;
-
-  </programlisting>
-  <para>
-        Querying the frequency in our case is relatively simple. Our radio card is
-        too dumb to let us query the signal strength so we remember our setting if 
-        we know it. All we have to do is copy it to the user.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCSFREQ:
-                {
-                        u32 freq;
-                        if(copy_from_user(arg, &amp;freq, 
-                                sizeof(unsigned long))!=0)
-                                return -EFAULT;
-                        if(hardware_set_freq(freq)&lt;0)
-                                return -EINVAL;
-                        current_freq = freq;
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        Setting the frequency is a little more complex. We begin by copying the
-        desired frequency into kernel space. Next we call a hardware specific routine
-        to set the radio up. This might be as simple as some scaling and a few
-        writes to an I/O port. For most radio cards it turns out a good deal more
-        complicated and may involve programming things like a phase locked loop on
-        the card. This is what documentation is for. 
-  </para>
-  <para>
-        The final set of operations we need to provide for our radio are the 
-        volume controls. Not all radio cards can even do volume control. After all
-        there is a perfectly good volume control on the sound card. We will assume
-        our radio card has a simple 4 step volume control.
-  </para>
-  <para>
-        There are two ioctls with audio we need to support
-  </para>
-  <programlisting>
-
-static int current_volume=0;
-
-                case VIDIOCGAUDIO:
-                {
-                        struct video_audio v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.audio != 0)
-                                return -EINVAL;
-                        v.volume = 16384*current_volume;
-                        v.step = 16384;
-                        strcpy(v.name, "Radio");
-                        v.mode = VIDEO_SOUND_MONO;
-                        v.balance = 0;
-                        v.base = 0;
-                        v.treble = 0;
-                        
-                        if(copy_to_user(arg. &amp;v, sizeof(v)))
-                                return -EFAULT;
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        Much like the tuner we start by copying the user structure into kernel
-        space. Again we check if the user has asked for a valid audio input. We have
-        only input 0 and we punt if they ask for another input.
-  </para>
-  <para>
-        Then we fill in the video_audio structure. This has the following format
-  </para>
-   <table frame="all" id="video_audio_fields"><title>struct video_audio fields</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-   <entry>audio</entry><entry>The input the user wishes to query</entry>
-   </row><row>
-   <entry>volume</entry><entry>The volume setting on a scale of 0-65535</entry>
-   </row><row>
-   <entry>base</entry><entry>The base level on a scale of 0-65535</entry>
-   </row><row>
-   <entry>treble</entry><entry>The treble level on a scale of 0-65535</entry>
-   </row><row>
-   <entry>flags</entry><entry>The features this audio device supports
-   </entry>
-   </row><row>
-   <entry>name</entry><entry>A text name to display to the user. We picked
-                        "Radio" as it explains things quite nicely.</entry>
-   </row><row>
-   <entry>mode</entry><entry>The current reception mode for the audio
-
-                We report MONO because our card is too stupid to know if it is in
-                mono or stereo. 
-   </entry>
-   </row><row>
-   <entry>balance</entry><entry>The stereo balance on a scale of 0-65535, 32768 is
-                        middle.</entry>
-   </row><row>
-   <entry>step</entry><entry>The step by which the volume control jumps. This is
-                        used to help make it easy for applications to set 
-                        slider behaviour.</entry>
-   </row>
-   </tbody>
-   </tgroup>
-   </table>
-
-   <table frame="all" id="video_audio_flags"><title>struct video_audio flags</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-                <entry>VIDEO_AUDIO_MUTE</entry><entry>The audio is currently muted. We
-                                        could fake this in our driver but we
-                                        choose not to bother.</entry>
-   </row><row>
-                <entry>VIDEO_AUDIO_MUTABLE</entry><entry>The input has a mute option</entry>
-   </row><row>
-                <entry>VIDEO_AUDIO_TREBLE</entry><entry>The  input has a treble control</entry>
-   </row><row>
-                <entry>VIDEO_AUDIO_BASS</entry><entry>The input has a base control</entry>
-   </row>
-   </tbody>
-   </tgroup>
-   </table>
-
-   <table frame="all" id="video_audio_modes"><title>struct video_audio modes</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-                <entry>VIDEO_SOUND_MONO</entry><entry>Mono sound</entry>
-   </row><row>
-                <entry>VIDEO_SOUND_STEREO</entry><entry>Stereo sound</entry>
-   </row><row>
-                <entry>VIDEO_SOUND_LANG1</entry><entry>Alternative language 1 (TV specific)</entry>
-   </row><row>
-                <entry>VIDEO_SOUND_LANG2</entry><entry>Alternative language 2 (TV specific)</entry>
-   </row>
-   </tbody>
-   </tgroup>
-   </table>
-  <para>
-        Having filled in the structure we copy it back to user space.
-  </para>
-  <para>
-        The VIDIOCSAUDIO ioctl allows the user to set the audio parameters in the
-        video_audio structure. The driver does its best to honour the request.
-  </para>
-  <programlisting>
-
-                case VIDIOCSAUDIO:
-                {
-                        struct video_audio v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.audio)
-                                return -EINVAL;
-                        current_volume = v/16384;
-                        hardware_set_volume(current_volume);
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        In our case there is very little that the user can set. The volume is
-        basically the limit. Note that we could pretend to have a mute feature
-        by rewriting this to 
-  </para>
-  <programlisting>
-
-                case VIDIOCSAUDIO:
-                {
-                        struct video_audio v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.audio)
-                                return -EINVAL;
-                        current_volume = v/16384;
-                        if(v.flags&amp;VIDEO_AUDIO_MUTE)
-                                hardware_set_volume(0);
-                        else
-                                hardware_set_volume(current_volume);
-                        current_muted = v.flags &amp; 
-                                              VIDEO_AUDIO_MUTE;
-                        return 0;
-                }
-
-  </programlisting>
-  <para>
-        This with the corresponding changes to the VIDIOCGAUDIO code to report the
-        state of the mute flag we save and to report the card has a mute function,
-        will allow applications to use a mute facility with this card. It is
-        questionable whether this is a good idea however. User applications can already
-        fake this themselves and kernel space is precious.
-  </para>
-  <para>
-        We now have a working radio ioctl handler. So we just wrap up the function
-  </para>
-  <programlisting>
-
-
-        }
-        return -ENOIOCTLCMD;
-}
-
-  </programlisting>
-  <para>
-        and pass the Video4Linux layer back an error so that it knows we did not
-        understand the request we got passed.
-  </para>
-  </sect1>
-  <sect1 id="modradio">
-  <title>Module Wrapper</title>
-  <para>
-        Finally we add in the usual module wrapping and the driver is done.
-  </para>
-  <programlisting>
-
-#ifndef MODULE
-
-static int io = 0x300;
-
-#else
-
-static int io = -1;
-
-#endif
-
-MODULE_AUTHOR("Alan Cox");
-MODULE_DESCRIPTION("A driver for an imaginary radio card.");
-module_param(io, int, 0444);
-MODULE_PARM_DESC(io, "I/O address of the card.");
-
-static int __init init(void)
-{
-        if(io==-1)
-        {
-                printk(KERN_ERR 
-         "You must set an I/O address with io=0x???\n");
-                return -EINVAL;
-        }
-        return myradio_init(NULL);
-}
-
-static void __exit cleanup(void)
-{
-        video_unregister_device(&amp;my_radio);
-        release_region(io, MY_IO_SIZE);
-}
-
-module_init(init);
-module_exit(cleanup);
-
-  </programlisting>
-  <para>
-        In this example we set the IO base by default if the driver is compiled into
-        the kernel: you can still set it using "my_radio.irq" if this file is called <filename>my_radio.c</filename>. For the module we require the
-        user sets the parameter. We set io to a nonsense port (-1) so that we can
-        tell if the user supplied an io parameter or not.
-  </para>
-  <para>
-        We use MODULE_ defines to give an author for the card driver and a
-        description. We also use them to declare that io is an integer and it is the
-        address of the card, and can be read by anyone from sysfs.
-  </para>
-  <para>
-        The clean-up routine unregisters the video_device we registered, and frees
-        up the I/O space. Note that the unregister takes the actual video_device
-        structure as its argument. Unlike the file operations structure which can be
-        shared by all instances of a device a video_device structure as an actual
-        instance of the device. If you are registering multiple radio devices you
-        need to fill in one structure per device (most likely by setting up a
-        template and copying it to each of the actual device structures).
-  </para>
-  </sect1>
-  </chapter>
-  <chapter id="Video_Capture_Devices">
-        <title>Video Capture Devices</title>
-  <sect1 id="introvid">
-  <title>Video Capture Device Types</title>
-  <para>
-        The video capture devices share the same interfaces as radio devices. In
-        order to explain the video capture interface I will use the example of a
-        camera that has no tuners or audio input. This keeps the example relatively
-        clean. To get both combine the two driver examples.
-  </para>
-  <para>
-        Video capture devices divide into four categories. A little technology
-        backgrounder. Full motion video even at television resolution (which is
-        actually fairly low) is pretty resource-intensive. You are continually
-        passing megabytes of data every second from the capture card to the display. 
-        several alternative approaches have emerged because copying this through the 
-        processor and the user program is a particularly bad idea .
-  </para>
-  <para>
-        The first is to add the television image onto the video output directly.
-        This is also how some 3D cards work. These basic cards can generally drop the
-        video into any chosen rectangle of the display. Cards like this, which
-        include most mpeg1 cards that used the feature connector,  aren't very
-        friendly in a windowing environment. They don't understand windows or
-        clipping. The video window is always on the top of the display.
-  </para>
-  <para>
-        Chroma keying is a technique used by cards to get around this. It is an old
-        television mixing trick where you mark all the areas you wish to replace
-        with a single clear colour that isn't used in the image - TV people use an
-        incredibly bright blue while computing people often use a particularly
-        virulent purple. Bright blue occurs on the desktop. Anyone with virulent
-        purple windows has another problem besides their TV overlay.
-  </para>
-  <para>
-        The third approach is to copy the data from the capture card to the video
-        card, but to do it directly across the PCI bus. This relieves the processor
-        from doing the work but does require some smartness on the part of the video
-        capture chip, as well as a suitable video card. Programming this kind of
-        card and more so debugging it can be extremely tricky. There are some quite
-        complicated interactions with the display and you may also have to cope with
-        various chipset bugs that show up when PCI cards start talking to each
-        other. 
-  </para>
-  <para>
-        To keep our example fairly simple we will assume a card that supports
-        overlaying a flat rectangular image onto the frame buffer output, and which
-        can also capture stuff into processor memory.
-  </para>
-  </sect1>
-  <sect1 id="regvid">
-  <title>Registering Video Capture Devices</title>
-  <para>
-        This time we need to add more functions for our camera device.
-  </para>
-  <programlisting>
-static struct video_device my_camera
-{
-        "My Camera",
-        VID_TYPE_OVERLAY|VID_TYPE_SCALES|\
-        VID_TYPE_CAPTURE|VID_TYPE_CHROMAKEY,
-        camera_open.
-        camera_close,
-        camera_read,      /* no read */
-        NULL,             /* no write */
-        camera_poll,      /* no poll */
-        camera_ioctl,
-        NULL,             /* no special init function */
-        NULL              /* no private data */
-};
-  </programlisting>
-  <para>
-        We need a read() function which is used for capturing data from
-        the card, and we need a poll function so that a driver can wait for the next
-        frame to be captured.
-  </para>
-  <para>
-        We use the extra video capability flags that did not apply to the
-        radio interface. The video related flags are
-  </para>
-   <table frame="all" id="Capture_Capabilities"><title>Capture Capabilities</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-<entry>VID_TYPE_CAPTURE</entry><entry>We support image capture</entry>
-</row><row>
-<entry>VID_TYPE_TELETEXT</entry><entry>A teletext capture device (vbi{n])</entry>
-</row><row>
-<entry>VID_TYPE_OVERLAY</entry><entry>The image can be directly overlaid onto the
-                                frame buffer</entry>
-</row><row>
-<entry>VID_TYPE_CHROMAKEY</entry><entry>Chromakey can be used to select which parts
-                                of the image to display</entry>
-</row><row>
-<entry>VID_TYPE_CLIPPING</entry><entry>It is possible to give the board a list of
-                                rectangles to draw around. </entry>
-</row><row>
-<entry>VID_TYPE_FRAMERAM</entry><entry>The video capture goes into the video memory
-                                and actually changes it. Applications need
-                                to know this so they can clean up after the
-                                card</entry>
-</row><row>
-<entry>VID_TYPE_SCALES</entry><entry>The image can be scaled to various sizes,
-                                rather than being a single fixed size.</entry>
-</row><row>
-<entry>VID_TYPE_MONOCHROME</entry><entry>The capture will be monochrome. This isn't a
-                                complete answer to the question since a mono
-                                camera on a colour capture card will still
-                                produce mono output.</entry>
-</row><row>
-<entry>VID_TYPE_SUBCAPTURE</entry><entry>The card allows only part of its field of
-                                view to be captured. This enables
-                                applications to avoid copying all of a large
-                                image into memory when only some section is
-                                relevant.</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-  <para>
-        We set VID_TYPE_CAPTURE so that we are seen as a capture card,
-        VID_TYPE_CHROMAKEY so the application knows it is time to draw in virulent
-        purple, and VID_TYPE_SCALES because we can be resized.
-  </para>
-  <para>
-        Our setup is fairly similar. This time we also want an interrupt line
-        for the 'frame captured' signal. Not all cards have this so some of them
-        cannot handle poll().
-  </para>
-  <programlisting>
-
-
-static int io = 0x320;
-static int irq = 11;
-
-int __init mycamera_init(struct video_init *v)
-{
-        if(!request_region(io, MY_IO_SIZE, "mycamera"))
-        {
-                printk(KERN_ERR 
-                      "mycamera: port 0x%03X is in use.\n", io);
-                return -EBUSY;
-        }
-
-        if(video_device_register(&amp;my_camera, 
-            VFL_TYPE_GRABBER)==-1) {
-                release_region(io, MY_IO_SIZE);
-                return -EINVAL;
-        }
-        return 0;
-}
-
-  </programlisting>
-  <para>
-        This is little changed from the needs of the radio card. We specify
-        VFL_TYPE_GRABBER this time as we want to be allocated a /dev/video name.
-  </para>
-  </sect1>
-  <sect1 id="opvid">
-  <title>Opening And Closing The Capture Device</title>
-  <programlisting>
-
-
-static int users = 0;
-
-static int camera_open(struct video_device *dev, int flags)
-{
-        if(users)
-                return -EBUSY;
-        if(request_irq(irq, camera_irq, 0, "camera", dev)&lt;0)
-                return -EBUSY;
-        users++;
-        return 0;
-}
-
-
-static int camera_close(struct video_device *dev)
-{
-        users--;
-        free_irq(irq, dev);
-}
-  </programlisting>
-  <para>
-        The open and close routines are also quite similar. The only real change is
-        that we now request an interrupt for the camera device interrupt line. If we
-        cannot get the interrupt we report EBUSY to the application and give up.
-  </para>
-  </sect1>
-  <sect1 id="irqvid">
-  <title>Interrupt Handling</title>
-  <para>
-        Our example handler is for an ISA bus device. If it was PCI you would be
-        able to share the interrupt and would have set IRQF_SHARED to indicate a
-        shared IRQ. We pass the device pointer as the interrupt routine argument. We
-        don't need to since we only support one card but doing this will make it
-        easier to upgrade the driver for multiple devices in the future.
-  </para>
-  <para>
-        Our interrupt routine needs to do little if we assume the card can simply
-        queue one frame to be read after it captures it. 
-  </para>
-  <programlisting>
-
-
-static struct wait_queue *capture_wait;
-static int capture_ready = 0;
-
-static void camera_irq(int irq, void *dev_id, 
-                          struct pt_regs *regs)
-{
-        capture_ready=1;
-        wake_up_interruptible(&amp;capture_wait);
-}
-  </programlisting>
-  <para>
-        The interrupt handler is nice and simple for this card as we are assuming
-        the card is buffering the frame for us. This means we have little to do but
-        wake up        anybody interested. We also set a capture_ready flag, as we may
-        capture a frame before an application needs it. In this case we need to know
-        that a frame is ready. If we had to collect the frame on the interrupt life
-        would be more complex.
-  </para>
-  <para>
-        The two new routines we need to supply are camera_read which returns a
-        frame, and camera_poll which waits for a frame to become ready.
-  </para>
-  <programlisting>
-
-
-static int camera_poll(struct video_device *dev, 
-       struct file *file, struct poll_table *wait)
-{
-        poll_wait(file, &amp;capture_wait, wait);
-        if(capture_read)
-                return POLLIN|POLLRDNORM;
-        return 0;
-}
-
-  </programlisting>
-  <para>
-        Our wait queue for polling is the capture_wait queue. This will cause the
-        task to be woken up by our camera_irq routine. We check capture_read to see
-        if there is an image present and if so report that it is readable.
-  </para>
-  </sect1>
-  <sect1 id="rdvid">
-  <title>Reading The Video Image</title>
-  <programlisting>
-
-
-static long camera_read(struct video_device *dev, char *buf,
-                                unsigned long count)
-{
-        struct wait_queue wait = { current, NULL };
-        u8 *ptr;
-        int len;
-        int i;
-
-        add_wait_queue(&amp;capture_wait, &amp;wait);
-
-        while(!capture_ready)
-        {
-                if(file->flags&amp;O_NDELAY)
-                {
-                        remove_wait_queue(&amp;capture_wait, &amp;wait);
-                        current->state = TASK_RUNNING;
-                        return -EWOULDBLOCK;
-                }
-                if(signal_pending(current))
-                {
-                        remove_wait_queue(&amp;capture_wait, &amp;wait);
-                        current->state = TASK_RUNNING;
-                        return -ERESTARTSYS;
-                }
-                schedule();
-                current->state = TASK_INTERRUPTIBLE;
-        }
-        remove_wait_queue(&amp;capture_wait, &amp;wait);
-        current->state = TASK_RUNNING;
-
-  </programlisting>
-  <para>
-        The first thing we have to do is to ensure that the application waits until
-        the next frame is ready. The code here is almost identical to the mouse code
-        we used earlier in this chapter. It is one of the common building blocks of
-        Linux device driver code and probably one which you will find occurs in any
-        drivers you write.
-  </para>
-  <para>
-        We wait for a frame to be ready, or for a signal to interrupt our waiting. If a
-        signal occurs we need to return from the system call so that the signal can
-        be sent to the application itself. We also check to see if the user actually
-        wanted to avoid waiting - ie  if they are using non-blocking I/O and have other things 
-        to get on with.
-  </para>
-  <para>
-        Next we copy the data from the card to the user application. This is rarely
-        as easy as our example makes out. We will add capture_w, and capture_h here
-        to hold the width and height of the captured image. We assume the card only
-        supports 24bit RGB for now.
-  </para>
-  <programlisting>
-
-
-
-        capture_ready = 0;
-
-        ptr=(u8 *)buf;
-        len = capture_w * 3 * capture_h; /* 24bit RGB */
-
-        if(len>count)
-                len=count;  /* Doesn't all fit */
-
-        for(i=0; i&lt;len; i++)
-        {
-                put_user(inb(io+IMAGE_DATA), ptr);
-                ptr++;
-        }
-
-        hardware_restart_capture();
-                
-        return i;
-}
-
-  </programlisting>
-  <para>
-        For a real hardware device you would try to avoid the loop with put_user().
-        Each call to put_user() has a time overhead checking whether the accesses to user
-        space are allowed. It would be better to read a line into a temporary buffer
-        then copy this to user space in one go.
-  </para>
-  <para>
-        Having captured the image and put it into user space we can kick the card to
-        get the next frame acquired.
-  </para>
-  </sect1>
-  <sect1 id="iocvid">
-  <title>Video Ioctl Handling</title>
-  <para>
-        As with the radio driver the major control interface is via the ioctl()
-        function. Video capture devices support the same tuner calls as a radio
-        device and also support additional calls to control how the video functions
-        are handled. In this simple example the card has no tuners to avoid making
-        the code complex. 
-  </para>
-  <programlisting>
-
-
-
-static int camera_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
-        switch(cmd)
-        {
-                case VIDIOCGCAP:
-                {
-                        struct video_capability v;
-                        v.type = VID_TYPE_CAPTURE|\
-                                 VID_TYPE_CHROMAKEY|\
-                                 VID_TYPE_SCALES|\
-                                 VID_TYPE_OVERLAY;
-                        v.channels = 1;
-                        v.audios = 0;
-                        v.maxwidth = 640;
-                        v.minwidth = 16;
-                        v.maxheight = 480;
-                        v.minheight = 16;
-                        strcpy(v.name, "My Camera");
-                        if(copy_to_user(arg, &amp;v, sizeof(v)))
-                                return -EFAULT;
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        The first ioctl we must support and which all video capture and radio
-        devices are required to support is VIDIOCGCAP. This behaves exactly the same
-        as with a radio device. This time, however, we report the extra capabilities
-        we outlined earlier on when defining our video_dev structure.
-  </para>
-  <para>
-        We now set the video flags saying that we support overlay, capture,
-        scaling and chromakey. We also report size limits - our smallest image is
-        16x16 pixels, our largest is 640x480. 
-  </para>
-  <para>
-        To keep things simple we report no audio and no tuning capabilities at all.
-  </para>
-  <programlisting>        
-
-                case VIDIOCGCHAN:
-                {
-                        struct video_channel v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.channel != 0)
-                                return -EINVAL;
-                        v.flags = 0;
-                        v.tuners = 0;
-                        v.type = VIDEO_TYPE_CAMERA;
-                        v.norm = VIDEO_MODE_AUTO;
-                        strcpy(v.name, "Camera Input");break;
-                        if(copy_to_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        This follows what is very much the standard way an ioctl handler looks
-        in Linux. We copy the data into a kernel space variable and we check that the
-        request is valid (in this case that the input is 0). Finally we copy the
-        camera info back to the user.
-  </para>
-  <para>
-        The VIDIOCGCHAN ioctl allows a user to ask about video channels (that is
-        inputs to the video card). Our example card has a single camera input. The
-        fields in the structure are
-  </para>
-   <table frame="all" id="video_channel_fields"><title>struct video_channel fields</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-
-   <entry>channel</entry><entry>The channel number we are selecting</entry>
-   </row><row>
-   <entry>name</entry><entry>The name for this channel. This is intended
-                   to describe the port to the user.
-                   Appropriate names are therefore things like
-                   "Camera" "SCART input"</entry>
-   </row><row>
-   <entry>flags</entry><entry>Channel properties</entry>
-   </row><row>
-   <entry>type</entry><entry>Input type</entry>
-   </row><row>
-   <entry>norm</entry><entry>The current television encoding being used
-                   if relevant for this channel.
-    </entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-    <table frame="all" id="video_channel_flags"><title>struct video_channel flags</title>
-    <tgroup cols="2" align="left">
-    <tbody>
-    <row>
-        <entry>VIDEO_VC_TUNER</entry><entry>Channel has a tuner.</entry>
-   </row><row>
-        <entry>VIDEO_VC_AUDIO</entry><entry>Channel has audio.</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-    <table frame="all" id="video_channel_types"><title>struct video_channel types</title>
-    <tgroup cols="2" align="left">
-    <tbody>
-    <row>
-        <entry>VIDEO_TYPE_TV</entry><entry>Television input.</entry>
-   </row><row>
-        <entry>VIDEO_TYPE_CAMERA</entry><entry>Fixed camera input.</entry>
-   </row><row>
-       <entry>0</entry><entry>Type is unknown.</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-    <table frame="all" id="video_channel_norms"><title>struct video_channel norms</title>
-    <tgroup cols="2" align="left">
-    <tbody>
-    <row>
-        <entry>VIDEO_MODE_PAL</entry><entry>PAL encoded Television</entry>
-   </row><row>
-        <entry>VIDEO_MODE_NTSC</entry><entry>NTSC (US) encoded Television</entry>
-   </row><row>
-        <entry>VIDEO_MODE_SECAM</entry><entry>SECAM (French) Television </entry>
-   </row><row>
-        <entry>VIDEO_MODE_AUTO</entry><entry>Automatic switching, or format does not
-                                matter</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-    <para>
-        The corresponding VIDIOCSCHAN ioctl allows a user to change channel and to
-        request the norm is changed - for example to switch between a PAL or an NTSC
-        format camera.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCSCHAN:
-                {
-                        struct video_channel v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.channel != 0)
-                                return -EINVAL;
-                        if(v.norm != VIDEO_MODE_AUTO)
-                                return -EINVAL;
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        The implementation of this call in our driver is remarkably easy. Because we
-        are assuming fixed format hardware we need only check that the user has not
-        tried to change anything. 
-  </para>
-  <para>
-        The user also needs to be able to configure and adjust the picture they are
-        seeing. This is much like adjusting a television set. A user application
-        also needs to know the palette being used so that it knows how to display
-        the image that has been captured. The VIDIOCGPICT and VIDIOCSPICT ioctl
-        calls provide this information.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCGPICT
-                {
-                        struct video_picture v;
-                        v.brightness = hardware_brightness();
-                        v.hue = hardware_hue();
-                        v.colour = hardware_saturation();
-                        v.contrast = hardware_brightness();
-                        /* Not settable */
-                        v.whiteness = 32768;
-                        v.depth = 24;           /* 24bit */
-                        v.palette = VIDEO_PALETTE_RGB24;
-                        if(copy_to_user(&amp;v, arg, 
-                             sizeof(v)))
-                                return -EFAULT;
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        The brightness, hue, color, and contrast provide the picture controls that
-        are akin to a conventional television. Whiteness provides additional
-        control for greyscale images. All of these values are scaled between 0-65535
-        and have 32768 as the mid point setting. The scaling means that applications
-        do not have to worry about the capability range of the hardware but can let
-        it make a best effort attempt.
-  </para>
-  <para>
-        Our depth is 24, as this is in bits. We will be returning RGB24 format. This
-        has one byte of red, then one of green, then one of blue. This then repeats
-        for every other pixel in the image. The other common formats the interface 
-        defines are
-  </para>
-   <table frame="all" id="Framebuffer_Encodings"><title>Framebuffer Encodings</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-   <entry>GREY</entry><entry>Linear greyscale. This is for simple cameras and the
-                        like</entry>
-   </row><row>
-   <entry>RGB565</entry><entry>The top 5 bits hold 32 red levels, the next six bits
-                        hold green and the low 5 bits hold blue. </entry>
-   </row><row>
-   <entry>RGB555</entry><entry>The top bit is clear. The red green and blue levels
-                        each occupy five bits.</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-  <para>
-        Additional modes are support for YUV capture formats. These are common for
-        TV and video conferencing applications.
-  </para>
-  <para>
-        The VIDIOCSPICT ioctl allows a user to set some of the picture parameters.
-        Exactly which ones are supported depends heavily on the card itself. It is
-        possible to support many modes and effects in software. In general doing
-        this in the kernel is a bad idea. Video capture is a performance-sensitive
-        application and the programs can often do better if they aren't being
-        'helped' by an overkeen driver writer. Thus for our device we will report
-        RGB24 only and refuse to allow a change.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCSPICT:
-                {
-                        struct video_picture v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.depth!=24 || 
-                           v.palette != VIDEO_PALETTE_RGB24)
-                                return -EINVAL;
-                        set_hardware_brightness(v.brightness);
-                        set_hardware_hue(v.hue);
-                        set_hardware_saturation(v.colour);
-                        set_hardware_brightness(v.contrast);
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        We check the user has not tried to change the palette or the depth. We do
-        not want to carry out some of the changes and then return an error. This may
-        confuse the application which will be assuming no change occurred.
-  </para>
-  <para>
-        In much the same way as you need to be able to set the picture controls to
-        get the right capture images, many cards need to know what they are
-        displaying onto when generating overlay output. In some cases getting this
-        wrong even makes a nasty mess or may crash the computer. For that reason
-        the VIDIOCSBUF ioctl used to set up the frame buffer information may well
-        only be usable by root.
-  </para>
-  <para>
-        We will assume our card is one of the old ISA devices with feature connector
-        and only supports a couple of standard video modes. Very common for older
-        cards although the PCI devices are way smarter than this.
-  </para>
-  <programlisting>
-
-
-static struct video_buffer capture_fb;
-
-                case VIDIOCGFBUF:
-                {
-                        if(copy_to_user(arg, &amp;capture_fb, 
-                             sizeof(capture_fb)))
-                                return -EFAULT;
-                        return 0;
-                        
-                }
-
-
-  </programlisting>
-  <para>
-        We keep the frame buffer information in the format the ioctl uses. This
-        makes it nice and easy to work with in the ioctl calls.
-  </para>
-  <programlisting>
-
-                case VIDIOCSFBUF:
-                {
-                        struct video_buffer v;
-
-                        if(!capable(CAP_SYS_ADMIN))
-                                return -EPERM;
-
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.width!=320 &amp;&amp; v.width!=640)
-                                return -EINVAL;
-                        if(v.height!=200 &amp;&amp; v.height!=240 
-                                &amp;&amp; v.height!=400
-                                &amp;&amp; v.height !=480)
-                                return -EINVAL;
-                        memcpy(&amp;capture_fb, &amp;v, sizeof(v));
-                        hardware_set_fb(&amp;v);
-                        return 0;
-                }
-
-
-
-  </programlisting>
-  <para>
-        The capable() function checks a user has the required capability. The Linux
-        operating system has a set of about 30 capabilities indicating privileged
-        access to services. The default set up gives the superuser (uid 0) all of
-        them and nobody else has any.
-  </para>
-  <para>
-        We check that the user has the SYS_ADMIN capability, that is they are
-        allowed to operate as the machine administrator. We don't want anyone but
-        the administrator making a mess of the display.
-  </para>
-  <para>
-        Next we check for standard PC video modes (320 or 640 wide with either
-        EGA or VGA depths). If the mode is not a standard video mode we reject it as
-        not supported by our card. If the mode is acceptable we save it so that
-        VIDIOCFBUF will give the right answer next time it is called.  The
-        hardware_set_fb() function is some undescribed card specific function to
-        program the card for the desired mode.
-  </para>
-  <para>
-        Before the driver can display an overlay window it needs to know where the
-        window should be placed, and also how large it should be. If the card
-        supports clipping it needs to know which rectangles to omit from the
-        display. The video_window structure is used to describe the way the image 
-        should be displayed. 
-   </para>
-   <table frame="all" id="video_window_fields"><title>struct video_window fields</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-        <entry>width</entry><entry>The width in pixels of the desired image. The card
-                        may use a smaller size if this size is not available</entry>
-       </row><row>
-        <entry>height</entry><entry>The height of the image. The card may use a smaller
-                        size if this size is not available.</entry>
-       </row><row>
-        <entry>x</entry><entry>   The X position of the top left of the window. This
-                        is in pixels relative to the left hand edge of the
-                        picture. Not all cards can display images aligned on
-                        any pixel boundary. If the position is unsuitable
-                        the card adjusts the image right and reduces the
-                        width.</entry>
-       </row><row>
-        <entry>y</entry><entry>   The Y position of the top left of the window. This
-                        is counted in pixels relative to the top edge of the
-                        picture. As with the width if the card cannot
-                        display  starting on this line it will adjust the
-                        values.</entry>
-       </row><row>
-        <entry>chromakey</entry><entry>The colour (expressed in RGB32 format) for the
-                        chromakey colour if chroma keying is being used. </entry>
-       </row><row>
-        <entry>clips</entry><entry>An array of rectangles that must not be drawn
-                       over.</entry>
-       </row><row>
-        <entry>clipcount</entry><entry>The number of clips in this array.</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-    <para>
-        Each clip is a struct video_clip which has the following fields
-   </para>
-   <table frame="all" id="video_clip_fields"><title>video_clip fields</title>
-   <tgroup cols="2" align="left">
-   <tbody>
-   <row>
-        <entry>x, y</entry><entry>Co-ordinates relative to the display</entry>
-       </row><row>
-        <entry>width, height</entry><entry>Width and height in pixels</entry>
-       </row><row>
-        <entry>next</entry><entry>A spare field for the application to use</entry>
-    </row>
-    </tbody>
-    </tgroup>
-    </table>
-    <para>
-        The driver is required to ensure it always draws in the area requested or a        smaller area, and that it never draws in any of the areas that are clipped.
-        This may well mean it has to leave alone. small areas the application wished to be
-        drawn.
-  </para>
-  <para>
-        Our example card uses chromakey so does not have to address most of the
-        clipping.  We will add a video_window structure to our global variables to
-        remember our parameters, as we did with the frame buffer.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCGWIN:
-                {
-                        if(copy_to_user(arg, &amp;capture_win, 
-                            sizeof(capture_win)))
-                                return -EFAULT;
-                        return 0;
-                }
-
-
-                case VIDIOCSWIN:
-                {
-                        struct video_window v;
-                        if(copy_from_user(&amp;v, arg, sizeof(v)))
-                                return -EFAULT;
-                        if(v.width &gt; 640 || v.height &gt; 480)
-                                return -EINVAL;
-                        if(v.width &lt; 16 || v.height &lt; 16)
-                                return -EINVAL;
-                        hardware_set_key(v.chromakey);
-                        hardware_set_window(v);
-                        memcpy(&amp;capture_win, &amp;v, sizeof(v));
-                        capture_w = v.width;
-                        capture_h = v.height;
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        Because we are using Chromakey our setup is fairly simple. Mostly we have to
-        check the values are sane and load them into the capture card.
-  </para>
-  <para>
-        With all the setup done we can now turn on the actual capture/overlay. This
-        is done with the VIDIOCCAPTURE ioctl. This takes a single integer argument
-        where 0 is on and 1 is off.
-  </para>
-  <programlisting>
-
-
-                case VIDIOCCAPTURE:
-                {
-                        int v;
-                        if(get_user(v, (int *)arg))
-                                return -EFAULT;
-                        if(v==0)
-                                hardware_capture_off();
-                        else
-                        {
-                                if(capture_fb.width == 0 
-                                    || capture_w == 0)
-                                        return -EINVAL;
-                                hardware_capture_on();
-                        }
-                        return 0;
-                }
-
-
-  </programlisting>
-  <para>
-        We grab the flag from user space and either enable or disable according to
-        its value. There is one small corner case we have to consider here. Suppose
-        that the capture was requested before the video window or the frame buffer
-        had been set up. In those cases there will be unconfigured fields in our
-        card data, as well as unconfigured hardware settings. We check for this case and
-        return an error if the frame buffer or the capture window width is zero.
-  </para>
-  <programlisting>
-
-
-                default:
-                        return -ENOIOCTLCMD;
-        }
-}
-  </programlisting>
-  <para>
-
-        We don't need to support any other ioctls, so if we get this far, it is time
-        to tell the video layer that we don't now what the user is talking about.
-  </para>
-  </sect1>
-  <sect1 id="endvid">
-  <title>Other Functionality</title>
-  <para>
-        The Video4Linux layer supports additional features, including a high
-        performance mmap() based capture mode and capturing part of the image. 
-        These features are out of the scope of the book.  You should however have enough 
-        example code to implement most simple video4linux devices for radio and TV
-        cards.
-  </para>
-  </sect1>
-  </chapter>
-  <chapter id="bugs">
-     <title>Known Bugs And Assumptions</title>
-  <para>
-  <variablelist>
-    <varlistentry><term>Multiple Opens</term>
-    <listitem>
-    <para>
-        The driver assumes multiple opens should not be allowed. A driver
-        can work around this but not cleanly.
-    </para>
-    </listitem></varlistentry>
-
-    <varlistentry><term>API Deficiencies</term>
-    <listitem>
-    <para>
-        The existing API poorly reflects compression capable devices. There
-        are plans afoot to merge V4L, V4L2 and some other ideas into a
-        better interface.
-    </para>
-    </listitem></varlistentry>
-  </variablelist>
-
-  </para>
-  </chapter>
-
-  <chapter id="pubfunctions">
-     <title>Public Functions Provided</title>
-!Edrivers/media/video/v4l2-dev.c
-  </chapter>
-
-</book>
index 48a3955f05fcd9c5f7548aadf7557062f1aabdb1..8495fc970391b7d455455e31515705a1f3d8f0f4 100644 (file)
@@ -112,7 +112,7 @@ required reading:
 
     Other excellent descriptions of how to create patches properly are:
        "The Perfect Patch"
-               http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+               http://userweb.kernel.org/~akpm/stuff/tpp.txt
        "Linux kernel patch submission format"
                http://linux.yyz.us/patch-format.html
 
@@ -620,7 +620,7 @@ all time.  It should describe the patch completely, containing:
 For more details on what this should all look like, please see the
 ChangeLog section of the document:
   "The Perfect Patch"
-      http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+      http://userweb.kernel.org/~akpm/stuff/tpp.txt
 
 
 
index b9019ca872eaf6e670481733a2b1393866b51c63..74be14679ed891820cd9c3a7393007f8dd21d07d 100644 (file)
@@ -1,5 +1,5 @@
 Linux 2.4.2 Secure Attention Key (SAK) handling
-18 March 2001, Andrew Morton <akpm@osdl.org>
+18 March 2001, Andrew Morton
 
 An operating system's Secure Attention Key is a security tool which is
 provided as protection against trojan password capturing programs.  It
index 21f0795af20f1a6a3c34569f10ac05d72e8b75b4..ac5e0b2f1097c94333b9b6844bb708980786e028 100644 (file)
@@ -85,3 +85,6 @@ kernel patches.
 23: Tested after it has been merged into the -mm patchset to make sure
     that it still works with all of the other queued patches and various
     changes in the VM, VFS, and other subsystems.
+
+24: All memory barriers {e.g., barrier(), rmb(), wmb()} need a comment in the
+    source code that explains the logic of what they are doing and why.
index 24f2eb40cae5e00491204e11fe8db8afd16b4aef..99e72a81fa2fac5570708ed419e7a89b19040f1c 100644 (file)
@@ -41,7 +41,7 @@ Linux 2.4:
 Linux 2.6:
        The same rules apply as 2.4 except that you should follow linux-kernel
        to track changes in API's. The final contact point for Linux 2.6
-       submissions is Andrew Morton <akpm@osdl.org>.
+       submissions is Andrew Morton.
 
 What Criteria Determine Acceptance
 ----------------------------------
index f79ad9ff6031aa4ee622d9f0be3e0c1604e2d14b..f309d3c6221c3699a0c0b97fbe689faed09e4d2f 100644 (file)
@@ -77,7 +77,7 @@ Quilt:
 http://savannah.nongnu.org/projects/quilt
 
 Andrew Morton's patch scripts:
-http://www.zip.com.au/~akpm/linux/patches/
+http://userweb.kernel.org/~akpm/stuff/patch-scripts.tar.gz
 Instead of these scripts, quilt is the recommended patch management
 tool (see above).
 
@@ -405,7 +405,7 @@ person it names.  This tag documents that potentially interested parties
 have been included in the discussion
 
 
-14) Using Test-by: and Reviewed-by:
+14) Using Tested-by: and Reviewed-by:
 
 A Tested-by: tag indicates that the patch has been successfully tested (in
 some environment) by the person named.  This tag informs maintainers that
@@ -653,7 +653,7 @@ SECTION 3 - REFERENCES
 ----------------------
 
 Andrew Morton, "The perfect patch" (tpp).
-  <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
+  <http://userweb.kernel.org/~akpm/stuff/tpp.txt>
 
 Jeff Garzik, "Linux kernel patch submission format".
   <http://linux.yyz.us/patch-format.html>
@@ -672,4 +672,9 @@ Kernel Documentation/CodingStyle:
 
 Linus Torvalds's mail on the canonical patch format:
   <http://lkml.org/lkml/2005/4/7/183>
+
+Andi Kleen, "On submitting kernel patches"
+  Some strategies to get difficult or controversal changes in.
+  http://halobates.de/on-submitting-patches.pdf
+
 --
index e9dc8d86adc7c51e4f1f06598a5a2c4b3eb5cabb..e8ca040ba2cff4bb5b938939f75c1bb97f0610af 100644 (file)
@@ -246,7 +246,7 @@ will require extra work due to the application tag.
       retrieve the tag buffer using bio_integrity_get_tag().
 
 
-6.3 PASSING EXISTING INTEGRITY METADATA
+5.3 PASSING EXISTING INTEGRITY METADATA
 
     Filesystems that either generate their own integrity metadata or
     are capable of transferring IMD from user space can use the
@@ -283,7 +283,7 @@ will require extra work due to the application tag.
       integrity upon completion.
 
 
-6.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY
+5.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY
     METADATA
 
     To enable integrity exchange on a block device the gendisk must be
index 795a1dabe6c78c933fb3ecfe2d16c691c577323d..d9b086869a6054d9687ec51070cfceb51fab6a50 100644 (file)
@@ -27,7 +27,7 @@ operating system.
 The ETRAX 100LX chip
 --------------------
 
-For reference, plase see the press-release:
+For reference, please see the press-release:
 
 http://www.axis.com/news/us/001101_etrax.htm
 
diff --git a/Documentation/development-process/1.Intro b/Documentation/development-process/1.Intro
new file mode 100644 (file)
index 0000000..8cc2cba
--- /dev/null
@@ -0,0 +1,274 @@
+1: A GUIDE TO THE KERNEL DEVELOPMENT PROCESS
+
+The purpose of this document is to help developers (and their managers)
+work with the development community with a minimum of frustration.  It is
+an attempt to document how this community works in a way which is
+accessible to those who are not intimately familiar with Linux kernel
+development (or, indeed, free software development in general).  While
+there is some technical material here, this is very much a process-oriented
+discussion which does not require a deep knowledge of kernel programming to
+understand.
+
+
+1.1: EXECUTIVE SUMMARY
+
+The rest of this section covers the scope of the kernel development process
+and the kinds of frustrations that developers and their employers can
+encounter there.  There are a great many reasons why kernel code should be
+merged into the official ("mainline") kernel, including automatic
+availability to users, community support in many forms, and the ability to
+influence the direction of kernel development.  Code contributed to the
+Linux kernel must be made available under a GPL-compatible license.
+
+Section 2 introduces the development process, the kernel release cycle, and
+the mechanics of the merge window.  The various phases in the patch
+development, review, and merging cycle are covered.  There is some
+discussion of tools and mailing lists.  Developers wanting to get started
+with kernel development are encouraged to track down and fix bugs as an
+initial exercise.
+
+Section 3 covers early-stage project planning, with an emphasis on
+involving the development community as soon as possible.
+
+Section 4 is about the coding process; several pitfalls which have been
+encountered by other developers are discussed.  Some requirements for
+patches are covered, and there is an introduction to some of the tools
+which can help to ensure that kernel patches are correct.
+
+Section 5 talks about the process of posting patches for review.  To be
+taken seriously by the development community, patches must be properly
+formatted and described, and they must be sent to the right place.
+Following the advice in this section should help to ensure the best
+possible reception for your work.
+
+Section 6 covers what happens after posting patches; the job is far from
+done at that point.  Working with reviewers is a crucial part of the
+development process; this section offers a number of tips on how to avoid
+problems at this important stage.  Developers are cautioned against
+assuming that the job is done when a patch is merged into the mainline.
+
+Section 7 introduces a couple of "advanced" topics: managing patches with
+git and reviewing patches posted by others.
+
+Section 8 concludes the document with pointers to sources for more
+information on kernel development.
+
+
+1.2: WHAT THIS DOCUMENT IS ABOUT
+
+The Linux kernel, at over 6 million lines of code and well over 1000 active
+contributors, is one of the largest and most active free software projects
+in existence.  Since its humble beginning in 1991, this kernel has evolved
+into a best-of-breed operating system component which runs on pocket-sized
+digital music players, desktop PCs, the largest supercomputers in
+existence, and all types of systems in between.  It is a robust, efficient,
+and scalable solution for almost any situation.
+
+With the growth of Linux has come an increase in the number of developers
+(and companies) wishing to participate in its development.  Hardware
+vendors want to ensure that Linux supports their products well, making
+those products attractive to Linux users.  Embedded systems vendors, who
+use Linux as a component in an integrated product, want Linux to be as
+capable and well-suited to the task at hand as possible.  Distributors and
+other software vendors who base their products on Linux have a clear
+interest in the capabilities, performance, and reliability of the Linux
+kernel.  And end users, too, will often wish to change Linux to make it
+better suit their needs.
+
+One of the most compelling features of Linux is that it is accessible to
+these developers; anybody with the requisite skills can improve Linux and
+influence the direction of its development.  Proprietary products cannot
+offer this kind of openness, which is a characteristic of the free software
+process.  But, if anything, the kernel is even more open than most other
+free software projects.  A typical three-month kernel development cycle can
+involve over 1000 developers working for more than 100 different companies
+(or for no company at all).
+
+Working with the kernel development community is not especially hard.  But,
+that notwithstanding, many potential contributors have experienced
+difficulties when trying to do kernel work.  The kernel community has
+evolved its own distinct ways of operating which allow it to function
+smoothly (and produce a high-quality product) in an environment where
+thousands of lines of code are being changed every day.  So it is not
+surprising that Linux kernel development process differs greatly from
+proprietary development methods.
+
+The kernel's development process may come across as strange and
+intimidating to new developers, but there are good reasons and solid
+experience behind it.  A developer who does not understand the kernel
+community's ways (or, worse, who tries to flout or circumvent them) will
+have a frustrating experience in store.  The development community, while
+being helpful to those who are trying to learn, has little time for those
+who will not listen or who do not care about the development process.
+
+It is hoped that those who read this document will be able to avoid that
+frustrating experience.  There is a lot of material here, but the effort
+involved in reading it will be repaid in short order.  The development
+community is always in need of developers who will help to make the kernel
+better; the following text should help you - or those who work for you -
+join our community.
+
+
+1.3: CREDITS
+
+This document was written by Jonathan Corbet, corbet@lwn.net.  It has been
+improved by comments from Johannes Berg, James Berry, Alex Chiang, Roland
+Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh,
+Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata, and
+Jochen Voß. 
+
+This work was supported by the Linux Foundation; thanks especially to
+Amanda McPherson, who saw the value of this effort and made it all happen.
+
+
+1.4: THE IMPORTANCE OF GETTING CODE INTO THE MAINLINE
+
+Some companies and developers occasionally wonder why they should bother
+learning how to work with the kernel community and get their code into the
+mainline kernel (the "mainline" being the kernel maintained by Linus
+Torvalds and used as a base by Linux distributors).  In the short term,
+contributing code can look like an avoidable expense; it seems easier to
+just keep the code separate and support users directly.  The truth of the
+matter is that keeping code separate ("out of tree") is a false economy.
+
+As a way of illustrating the costs of out-of-tree code, here are a few
+relevant aspects of the kernel development process; most of these will be
+discussed in greater detail later in this document.  Consider:
+
+- Code which has been merged into the mainline kernel is available to all
+  Linux users.  It will automatically be present on all distributions which
+  enable it.  There is no need for driver disks, downloads, or the hassles
+  of supporting multiple versions of multiple distributions; it all just
+  works, for the developer and for the user.  Incorporation into the
+  mainline solves a large number of distribution and support problems.
+
+- While kernel developers strive to maintain a stable interface to user
+  space, the internal kernel API is in constant flux.  The lack of a stable
+  internal interface is a deliberate design decision; it allows fundamental
+  improvements to be made at any time and results in higher-quality code.
+  But one result of that policy is that any out-of-tree code requires
+  constant upkeep if it is to work with new kernels.  Maintaining
+  out-of-tree code requires significant amounts of work just to keep that
+  code working.
+
+  Code which is in the mainline, instead, does not require this work as the
+  result of a simple rule requiring any developer who makes an API change
+  to also fix any code that breaks as the result of that change.  So code
+  which has been merged into the mainline has significantly lower
+  maintenance costs.
+
+- Beyond that, code which is in the kernel will often be improved by other
+  developers.  Surprising results can come from empowering your user
+  community and customers to improve your product.
+
+- Kernel code is subjected to review, both before and after merging into
+  the mainline.  No matter how strong the original developer's skills are,
+  this review process invariably finds ways in which the code can be
+  improved.  Often review finds severe bugs and security problems.  This is
+  especially true for code which has been developed in a closed
+  environment; such code benefits strongly from review by outside
+  developers.  Out-of-tree code is lower-quality code.
+
+- Participation in the development process is your way to influence the
+  direction of kernel development.  Users who complain from the sidelines
+  are heard, but active developers have a stronger voice - and the ability
+  to implement changes which make the kernel work better for their needs.
+
+- When code is maintained separately, the possibility that a third party
+  will contribute a different implementation of a similar feature always
+  exists.  Should that happen, getting your code merged will become much
+  harder - to the point of impossibility.  Then you will be faced with the
+  unpleasant alternatives of either (1) maintaining a nonstandard feature
+  out of tree indefinitely, or (2) abandoning your code and migrating your
+  users over to the in-tree version.
+
+- Contribution of code is the fundamental action which makes the whole
+  process work.  By contributing your code you can add new functionality to
+  the kernel and provide capabilities and examples which are of use to
+  other kernel developers.  If you have developed code for Linux (or are
+  thinking about doing so), you clearly have an interest in the continued
+  success of this platform; contributing code is one of the best ways to
+  help ensure that success.
+
+All of the reasoning above applies to any out-of-tree kernel code,
+including code which is distributed in proprietary, binary-only form.
+There are, however, additional factors which should be taken into account
+before considering any sort of binary-only kernel code distribution.  These
+include:
+
+- The legal issues around the distribution of proprietary kernel modules
+  are cloudy at best; quite a few kernel copyright holders believe that
+  most binary-only modules are derived products of the kernel and that, as
+  a result, their distribution is a violation of the GNU General Public
+  license (about which more will be said below).  Your author is not a
+  lawyer, and nothing in this document can possibly be considered to be
+  legal advice.  The true legal status of closed-source modules can only be
+  determined by the courts.  But the uncertainty which haunts those modules
+  is there regardless.
+
+- Binary modules greatly increase the difficulty of debugging kernel
+  problems, to the point that most kernel developers will not even try.  So
+  the distribution of binary-only modules will make it harder for your
+  users to get support from the community.
+
+- Support is also harder for distributors of binary-only modules, who must
+  provide a version of the module for every distribution and every kernel
+  version they wish to support.  Dozens of builds of a single module can
+  be required to provide reasonably comprehensive coverage, and your users
+  will have to upgrade your module separately every time they upgrade their
+  kernel.
+
+- Everything that was said above about code review applies doubly to
+  closed-source code.  Since this code is not available at all, it cannot
+  have been reviewed by the community and will, beyond doubt, have serious
+  problems. 
+
+Makers of embedded systems, in particular, may be tempted to disregard much
+of what has been said in this section in the belief that they are shipping
+a self-contained product which uses a frozen kernel version and requires no
+more development after its release.  This argument misses the value of
+widespread code review and the value of allowing your users to add
+capabilities to your product.  But these products, too, have a limited
+commercial life, after which a new version must be released.  At that
+point, vendors whose code is in the mainline and well maintained will be
+much better positioned to get the new product ready for market quickly.
+
+
+1.5: LICENSING
+
+Code is contributed to the Linux kernel under a number of licenses, but all
+code must be compatible with version 2 of the GNU General Public License
+(GPLv2), which is the license covering the kernel distribution as a whole.
+In practice, that means that all code contributions are covered either by
+GPLv2 (with, optionally, language allowing distribution under later
+versions of the GPL) or the three-clause BSD license.  Any contributions
+which are not covered by a compatible license will not be accepted into the
+kernel.
+
+Copyright assignments are not required (or requested) for code contributed
+to the kernel.  All code merged into the mainline kernel retains its
+original ownership; as a result, the kernel now has thousands of owners.
+
+One implication of this ownership structure is that any attempt to change
+the licensing of the kernel is doomed to almost certain failure.  There are
+few practical scenarios where the agreement of all copyright holders could
+be obtained (or their code removed from the kernel).  So, in particular,
+there is no prospect of a migration to version 3 of the GPL in the
+foreseeable future.
+
+It is imperative that all code contributed to the kernel be legitimately
+free software.  For that reason, code from anonymous (or pseudonymous)
+contributors will not be accepted.  All contributors are required to "sign
+off" on their code, stating that the code can be distributed with the
+kernel under the GPL.  Code which has not been licensed as free software by
+its owner, or which risks creating copyright-related problems for the
+kernel (such as code which derives from reverse-engineering efforts lacking
+proper safeguards) cannot be contributed.
+
+Questions about copyright-related issues are common on Linux development
+mailing lists.  Such questions will normally receive no shortage of
+answers, but one should bear in mind that the people answering those
+questions are not lawyers and cannot provide legal advice.  If you have
+legal questions relating to Linux source code, there is no substitute for
+talking with a lawyer who understands this field.  Relying on answers
+obtained on technical mailing lists is a risky affair.
diff --git a/Documentation/development-process/2.Process b/Documentation/development-process/2.Process
new file mode 100644 (file)
index 0000000..d750321
--- /dev/null
@@ -0,0 +1,459 @@
+2: HOW THE DEVELOPMENT PROCESS WORKS
+
+Linux kernel development in the early 1990's was a pretty loose affair,
+with relatively small numbers of users and developers involved.  With a
+user base in the millions and with some 2,000 developers involved over the
+course of one year, the kernel has since had to evolve a number of
+processes to keep development happening smoothly.  A solid understanding of
+how the process works is required in order to be an effective part of it.
+
+
+2.1: THE BIG PICTURE
+
+The kernel developers use a loosely time-based release process, with a new
+major kernel release happening every two or three months.  The recent
+release history looks like this:
+
+       2.6.26  July 13, 2008
+       2.6.25  April 16, 2008
+       2.6.24  January 24, 2008
+       2.6.23  October 9, 2007
+       2.6.22  July 8, 2007
+       2.6.21  April 25, 2007
+       2.6.20  February 4, 2007
+
+Every 2.6.x release is a major kernel release with new features, internal
+API changes, and more.  A typical 2.6 release can contain over 10,000
+changesets with changes to several hundred thousand lines of code.  2.6 is
+thus the leading edge of Linux kernel development; the kernel uses a
+rolling development model which is continually integrating major changes.
+
+A relatively straightforward discipline is followed with regard to the
+merging of patches for each release.  At the beginning of each development
+cycle, the "merge window" is said to be open.  At that time, code which is
+deemed to be sufficiently stable (and which is accepted by the development
+community) is merged into the mainline kernel.  The bulk of changes for a
+new development cycle (and all of the major changes) will be merged during
+this time, at a rate approaching 1,000 changes ("patches," or "changesets")
+per day.
+
+(As an aside, it is worth noting that the changes integrated during the
+merge window do not come out of thin air; they have been collected, tested,
+and staged ahead of time.  How that process works will be described in
+detail later on).
+
+The merge window lasts for two weeks.  At the end of this time, Linus
+Torvalds will declare that the window is closed and release the first of
+the "rc" kernels.  For the kernel which is destined to be 2.6.26, for
+example, the release which happens at the end of the merge window will be
+called 2.6.26-rc1.  The -rc1 release is the signal that the time to merge
+new features has passed, and that the time to stabilize the next kernel has
+begun.
+
+Over the next six to ten weeks, only patches which fix problems should be
+submitted to the mainline.  On occasion a more significant change will be
+allowed, but such occasions are rare; developers who try to merge new
+features outside of the merge window tend to get an unfriendly reception.
+As a general rule, if you miss the merge window for a given feature, the
+best thing to do is to wait for the next development cycle.  (An occasional
+exception is made for drivers for previously-unsupported hardware; if they
+touch no in-tree code, they cannot cause regressions and should be safe to
+add at any time).
+
+As fixes make their way into the mainline, the patch rate will slow over
+time.  Linus releases new -rc kernels about once a week; a normal series
+will get up to somewhere between -rc6 and -rc9 before the kernel is
+considered to be sufficiently stable and the final 2.6.x release is made.
+At that point the whole process starts over again.
+
+As an example, here is how the 2.6.25 development cycle went (all dates in
+2008): 
+
+       January 24      2.6.24 stable release
+       February 10     2.6.25-rc1, merge window closes
+       February 15     2.6.25-rc2
+       February 24     2.6.25-rc3
+       March 4         2.6.25-rc4
+       March 9         2.6.25-rc5
+       March 16        2.6.25-rc6
+       March 25        2.6.25-rc7
+       April 1         2.6.25-rc8
+       April 11        2.6.25-rc9
+       April 16        2.6.25 stable release
+
+How do the developers decide when to close the development cycle and create
+the stable release?  The most significant metric used is the list of
+regressions from previous releases.  No bugs are welcome, but those which
+break systems which worked in the past are considered to be especially
+serious.  For this reason, patches which cause regressions are looked upon
+unfavorably and are quite likely to be reverted during the stabilization
+period. 
+
+The developers' goal is to fix all known regressions before the stable
+release is made.  In the real world, this kind of perfection is hard to
+achieve; there are just too many variables in a project of this size.
+There comes a point where delaying the final release just makes the problem
+worse; the pile of changes waiting for the next merge window will grow
+larger, creating even more regressions the next time around.  So most 2.6.x
+kernels go out with a handful of known regressions though, hopefully, none
+of them are serious.
+
+Once a stable release is made, its ongoing maintenance is passed off to the
+"stable team," currently comprised of Greg Kroah-Hartman and Chris Wright.
+The stable team will release occasional updates to the stable release using
+the 2.6.x.y numbering scheme.  To be considered for an update release, a
+patch must (1) fix a significant bug, and (2) already be merged into the
+mainline for the next development kernel.  Continuing our 2.6.25 example,
+the history (as of this writing) is:
+
+       May 1           2.6.25.1
+       May 6           2.6.25.2 
+       May 9           2.6.25.3 
+       May 15          2.6.25.4
+       June 7          2.6.25.5
+       June 9          2.6.25.6
+       June 16         2.6.25.7
+       June 21         2.6.25.8
+       June 24         2.6.25.9
+
+Stable updates for a given kernel are made for approximately six months;
+after that, the maintenance of stable releases is solely the responsibility
+of the distributors which have shipped that particular kernel.
+
+
+2.2: THE LIFECYCLE OF A PATCH
+
+Patches do not go directly from the developer's keyboard into the mainline
+kernel.  There is, instead, a somewhat involved (if somewhat informal)
+process designed to ensure that each patch is reviewed for quality and that
+each patch implements a change which is desirable to have in the mainline.
+This process can happen quickly for minor fixes, or, in the case of large
+and controversial changes, go on for years.  Much developer frustration
+comes from a lack of understanding of this process or from attempts to
+circumvent it.  
+
+In the hopes of reducing that frustration, this document will describe how
+a patch gets into the kernel.  What follows below is an introduction which
+describes the process in a somewhat idealized way.  A much more detailed
+treatment will come in later sections.
+
+The stages that a patch goes through are, generally:
+
+ - Design.  This is where the real requirements for the patch - and the way
+   those requirements will be met - are laid out.  Design work is often
+   done without involving the community, but it is better to do this work
+   in the open if at all possible; it can save a lot of time redesigning
+   things later.
+
+ - Early review.  Patches are posted to the relevant mailing list, and
+   developers on that list reply with any comments they may have.  This
+   process should turn up any major problems with a patch if all goes
+   well.
+
+ - Wider review.  When the patch is getting close to ready for mainline
+   inclusion, it will be accepted by a relevant subsystem maintainer -
+   though this acceptance is not a guarantee that the patch will make it
+   all the way to the mainline.  The patch will show up in the maintainer's
+   subsystem tree and into the staging trees (described below).  When the
+   process works, this step leads to more extensive review of the patch and
+   the discovery of any problems resulting from the integration of this
+   patch with work being done by others.
+
+ - Merging into the mainline.  Eventually, a successful patch will be
+   merged into the mainline repository managed by Linus Torvalds.  More
+   comments and/or problems may surface at this time; it is important that
+   the developer be responsive to these and fix any issues which arise.
+
+ - Stable release.  The number of users potentially affected by the patch
+   is now large, so, once again, new problems may arise.
+
+ - Long-term maintenance.  While it is certainly possible for a developer
+   to forget about code after merging it, that sort of behavior tends to
+   leave a poor impression in the development community.  Merging code
+   eliminates some of the maintenance burden, in that others will fix
+   problems caused by API changes.  But the original developer should
+   continue to take responsibility for the code if it is to remain useful
+   in the longer term.
+
+One of the largest mistakes made by kernel developers (or their employers)
+is to try to cut the process down to a single "merging into the mainline"
+step.  This approach invariably leads to frustration for everybody
+involved.
+
+
+2.3: HOW PATCHES GET INTO THE KERNEL
+
+There is exactly one person who can merge patches into the mainline kernel
+repository: Linus Torvalds.  But, of the over 12,000 patches which went
+into the 2.6.25 kernel, only 250 (around 2%) were directly chosen by Linus
+himself.  The kernel project has long since grown to a size where no single
+developer could possibly inspect and select every patch unassisted.  The
+way the kernel developers have addressed this growth is through the use of
+a lieutenant system built around a chain of trust.
+
+The kernel code base is logically broken down into a set of subsystems:
+networking, specific architecture support, memory management, video
+devices, etc.  Most subsystems have a designated maintainer, a developer
+who has overall responsibility for the code within that subsystem.  These
+subsystem maintainers are the gatekeepers (in a loose way) for the portion
+of the kernel they manage; they are the ones who will (usually) accept a
+patch for inclusion into the mainline kernel.
+
+Subsystem maintainers each manage their own version of the kernel source
+tree, usually (but certainly not always) using the git source management
+tool.  Tools like git (and related tools like quilt or mercurial) allow
+maintainers to track a list of patches, including authorship information
+and other metadata.  At any given time, the maintainer can identify which
+patches in his or her repository are not found in the mainline.
+
+When the merge window opens, top-level maintainers will ask Linus to "pull"
+the patches they have selected for merging from their repositories.  If
+Linus agrees, the stream of patches will flow up into his repository,
+becoming part of the mainline kernel.  The amount of attention that Linus
+pays to specific patches received in a pull operation varies.  It is clear
+that, sometimes, he looks quite closely.  But, as a general rule, Linus
+trusts the subsystem maintainers to not send bad patches upstream.
+
+Subsystem maintainers, in turn, can pull patches from other maintainers.
+For example, the networking tree is built from patches which accumulated
+first in trees dedicated to network device drivers, wireless networking,
+etc.  This chain of repositories can be arbitrarily long, though it rarely
+exceeds two or three links.  Since each maintainer in the chain trusts
+those managing lower-level trees, this process is known as the "chain of
+trust." 
+
+Clearly, in a system like this, getting patches into the kernel depends on
+finding the right maintainer.  Sending patches directly to Linus is not
+normally the right way to go.
+
+
+2.4: STAGING TREES
+
+The chain of subsystem trees guides the flow of patches into the kernel,
+but it also raises an interesting question: what if somebody wants to look
+at all of the patches which are being prepared for the next merge window?
+Developers will be interested in what other changes are pending to see
+whether there are any conflicts to worry about; a patch which changes a
+core kernel function prototype, for example, will conflict with any other
+patches which use the older form of that function.  Reviewers and testers
+want access to the changes in their integrated form before all of those
+changes land in the mainline kernel.  One could pull changes from all of
+the interesting subsystem trees, but that would be a big and error-prone
+job.
+
+The answer comes in the form of staging trees, where subsystem trees are
+collected for testing and review.  The older of these trees, maintained by
+Andrew Morton, is called "-mm" (for memory management, which is how it got
+started).  The -mm tree integrates patches from a long list of subsystem
+trees; it also has some patches aimed at helping with debugging.  
+
+Beyond that, -mm contains a significant collection of patches which have
+been selected by Andrew directly.  These patches may have been posted on a
+mailing list, or they may apply to a part of the kernel for which there is
+no designated subsystem tree.  As a result, -mm operates as a sort of
+subsystem tree of last resort; if there is no other obvious path for a
+patch into the mainline, it is likely to end up in -mm.  Miscellaneous
+patches which accumulate in -mm will eventually either be forwarded on to
+an appropriate subsystem tree or be sent directly to Linus.  In a typical
+development cycle, approximately 10% of the patches going into the mainline
+get there via -mm.
+
+The current -mm patch can always be found from the front page of
+
+       http://kernel.org/
+
+Those who want to see the current state of -mm can get the "-mm of the
+moment" tree, found at:
+
+       http://userweb.kernel.org/~akpm/mmotm/
+
+Use of the MMOTM tree is likely to be a frustrating experience, though;
+there is a definite chance that it will not even compile.
+
+The other staging tree, started more recently, is linux-next, maintained by
+Stephen Rothwell.  The linux-next tree is, by design, a snapshot of what
+the mainline is expected to look like after the next merge window closes.
+Linux-next trees are announced on the linux-kernel and linux-next mailing
+lists when they are assembled; they can be downloaded from:
+
+       http://www.kernel.org/pub/linux/kernel/people/sfr/linux-next/
+
+Some information about linux-next has been gathered at:
+
+       http://linux.f-seidel.de/linux-next/pmwiki/
+
+How the linux-next tree will fit into the development process is still
+changing.  As of this writing, the first full development cycle involving
+linux-next (2.6.26) is coming to an end; thus far, it has proved to be a
+valuable resource for finding and fixing integration problems before the
+beginning of the merge window.  See http://lwn.net/Articles/287155/ for
+more information on how linux-next has worked to set up the 2.6.27 merge
+window.
+
+Some developers have begun to suggest that linux-next should be used as the
+target for future development as well.  The linux-next tree does tend to be
+far ahead of the mainline and is more representative of the tree into which
+any new work will be merged.  The downside to this idea is that the
+volatility of linux-next tends to make it a difficult development target.
+See http://lwn.net/Articles/289013/ for more information on this topic, and
+stay tuned; much is still in flux where linux-next is involved.
+
+
+2.5: TOOLS
+
+As can be seen from the above text, the kernel development process depends
+heavily on the ability to herd collections of patches in various
+directions.  The whole thing would not work anywhere near as well as it
+does without suitably powerful tools.  Tutorials on how to use these tools
+are well beyond the scope of this document, but there is space for a few
+pointers.
+
+By far the dominant source code management system used by the kernel
+community is git.  Git is one of a number of distributed version control
+systems being developed in the free software community.  It is well tuned
+for kernel development, in that it performs quite well when dealing with
+large repositories and large numbers of patches.  It also has a reputation
+for being difficult to learn and use, though it has gotten better over
+time.  Some sort of familiarity with git is almost a requirement for kernel
+developers; even if they do not use it for their own work, they'll need git
+to keep up with what other developers (and the mainline) are doing.
+
+Git is now packaged by almost all Linux distributions.  There is a home
+page at 
+
+       http://git.or.cz/
+
+That page has pointers to documentation and tutorials.  One should be
+aware, in particular, of the Kernel Hacker's Guide to git, which has
+information specific to kernel development:
+
+       http://linux.yyz.us/git-howto.html
+
+Among the kernel developers who do not use git, the most popular choice is
+almost certainly Mercurial:
+
+       http://www.selenic.com/mercurial/
+
+Mercurial shares many features with git, but it provides an interface which
+many find easier to use.
+
+The other tool worth knowing about is Quilt:
+
+       http://savannah.nongnu.org/projects/quilt/
+
+Quilt is a patch management system, rather than a source code management
+system.  It does not track history over time; it is, instead, oriented
+toward tracking a specific set of changes against an evolving code base.
+Some major subsystem maintainers use quilt to manage patches intended to go
+upstream.  For the management of certain kinds of trees (-mm, for example),
+quilt is the best tool for the job.
+
+
+2.6: MAILING LISTS
+
+A great deal of Linux kernel development work is done by way of mailing
+lists.  It is hard to be a fully-functioning member of the community
+without joining at least one list somewhere.  But Linux mailing lists also
+represent a potential hazard to developers, who risk getting buried under a
+load of electronic mail, running afoul of the conventions used on the Linux
+lists, or both.
+
+Most kernel mailing lists are run on vger.kernel.org; the master list can
+be found at:
+
+       http://vger.kernel.org/vger-lists.html
+
+There are lists hosted elsewhere, though; a number of them are at
+lists.redhat.com.
+
+The core mailing list for kernel development is, of course, linux-kernel.
+This list is an intimidating place to be; volume can reach 500 messages per
+day, the amount of noise is high, the conversation can be severely
+technical, and participants are not always concerned with showing a high
+degree of politeness.  But there is no other place where the kernel
+development community comes together as a whole; developers who avoid this
+list will miss important information.
+
+There are a few hints which can help with linux-kernel survival:
+
+- Have the list delivered to a separate folder, rather than your main
+  mailbox.  One must be able to ignore the stream for sustained periods of
+  time.
+
+- Do not try to follow every conversation - nobody else does.  It is
+  important to filter on both the topic of interest (though note that
+  long-running conversations can drift away from the original subject
+  without changing the email subject line) and the people who are
+  participating.  
+
+- Do not feed the trolls.  If somebody is trying to stir up an angry
+  response, ignore them.
+
+- When responding to linux-kernel email (or that on other lists) preserve
+  the Cc: header for all involved.  In the absence of a strong reason (such
+  as an explicit request), you should never remove recipients.  Always make
+  sure that the person you are responding to is in the Cc: list.  This
+  convention also makes it unnecessary to explicitly ask to be copied on
+  replies to your postings.
+
+- Search the list archives (and the net as a whole) before asking
+  questions.  Some developers can get impatient with people who clearly
+  have not done their homework.
+
+- Avoid top-posting (the practice of putting your answer above the quoted
+  text you are responding to).  It makes your response harder to read and
+  makes a poor impression.
+
+- Ask on the correct mailing list.  Linux-kernel may be the general meeting
+  point, but it is not the best place to find developers from all
+  subsystems.
+
+The last point - finding the correct mailing list - is a common place for
+beginning developers to go wrong.  Somebody who asks a networking-related
+question on linux-kernel will almost certainly receive a polite suggestion
+to ask on the netdev list instead, as that is the list frequented by most
+networking developers.  Other lists exist for the SCSI, video4linux, IDE,
+filesystem, etc. subsystems.  The best place to look for mailing lists is
+in the MAINTAINERS file packaged with the kernel source.
+
+
+2.7: GETTING STARTED WITH KERNEL DEVELOPMENT
+
+Questions about how to get started with the kernel development process are
+common - from both individuals and companies.  Equally common are missteps
+which make the beginning of the relationship harder than it has to be.
+
+Companies often look to hire well-known developers to get a development
+group started.  This can, in fact, be an effective technique.  But it also
+tends to be expensive and does not do much to grow the pool of experienced
+kernel developers.  It is possible to bring in-house developers up to speed
+on Linux kernel development, given the investment of a bit of time.  Taking
+this time can endow an employer with a group of developers who understand
+the kernel and the company both, and who can help to train others as well.
+Over the medium term, this is often the more profitable approach.
+
+Individual developers are often, understandably, at a loss for a place to
+start.  Beginning with a large project can be intimidating; one often wants
+to test the waters with something smaller first.  This is the point where
+some developers jump into the creation of patches fixing spelling errors or
+minor coding style issues.  Unfortunately, such patches create a level of
+noise which is distracting for the development community as a whole, so,
+increasingly, they are looked down upon.  New developers wishing to
+introduce themselves to the community will not get the sort of reception
+they wish for by these means.
+
+Andrew Morton gives this advice for aspiring kernel developers
+
+       The #1 project for all kernel beginners should surely be "make sure
+       that the kernel runs perfectly at all times on all machines which
+       you can lay your hands on".  Usually the way to do this is to work
+       with others on getting things fixed up (this can require
+       persistence!) but that's fine - it's a part of kernel development.
+
+(http://lwn.net/Articles/283982/).
+
+In the absence of obvious problems to fix, developers are advised to look
+at the current lists of regressions and open bugs in general.  There is
+never any shortage of issues in need of fixing; by addressing these issues,
+developers will gain experience with the process while, at the same time,
+building respect with the rest of the development community.
diff --git a/Documentation/development-process/3.Early-stage b/Documentation/development-process/3.Early-stage
new file mode 100644 (file)
index 0000000..307a159
--- /dev/null
@@ -0,0 +1,195 @@
+3: EARLY-STAGE PLANNING
+
+When contemplating a Linux kernel development project, it can be tempting
+to jump right in and start coding.  As with any significant project,
+though, much of the groundwork for success is best laid before the first
+line of code is written.  Some time spent in early planning and
+communication can save far more time later on.
+
+
+3.1: SPECIFYING THE PROBLEM
+
+Like any engineering project, a successful kernel enhancement starts with a
+clear description of the problem to be solved.  In some cases, this step is
+easy: when a driver is needed for a specific piece of hardware, for
+example.  In others, though, it is tempting to confuse the real problem
+with the proposed solution, and that can lead to difficulties.
+
+Consider an example: some years ago, developers working with Linux audio
+sought a way to run applications without dropouts or other artifacts caused
+by excessive latency in the system.  The solution they arrived at was a
+kernel module intended to hook into the Linux Security Module (LSM)
+framework; this module could be configured to give specific applications
+access to the realtime scheduler.  This module was implemented and sent to
+the linux-kernel mailing list, where it immediately ran into problems.
+
+To the audio developers, this security module was sufficient to solve their
+immediate problem.  To the wider kernel community, though, it was seen as a
+misuse of the LSM framework (which is not intended to confer privileges
+onto processes which they would not otherwise have) and a risk to system
+stability.  Their preferred solutions involved realtime scheduling access
+via the rlimit mechanism for the short term, and ongoing latency reduction
+work in the long term.
+
+The audio community, however, could not see past the particular solution
+they had implemented; they were unwilling to accept alternatives.  The
+resulting disagreement left those developers feeling disillusioned with the
+entire kernel development process; one of them went back to an audio list
+and posted this:
+
+       There are a number of very good Linux kernel developers, but they
+       tend to get outshouted by a large crowd of arrogant fools. Trying
+       to communicate user requirements to these people is a waste of
+       time. They are much too "intelligent" to listen to lesser mortals.
+
+(http://lwn.net/Articles/131776/).
+
+The reality of the situation was different; the kernel developers were far
+more concerned about system stability, long-term maintenance, and finding
+the right solution to the problem than they were with a specific module.
+The moral of the story is to focus on the problem - not a specific solution
+- and to discuss it with the development community before investing in the
+creation of a body of code.
+
+So, when contemplating a kernel development project, one should obtain
+answers to a short set of questions:
+
+ - What, exactly, is the problem which needs to be solved?
+
+ - Who are the users affected by this problem?  Which use cases should the
+   solution address?
+
+ - How does the kernel fall short in addressing that problem now?
+
+Only then does it make sense to start considering possible solutions.
+
+
+3.2: EARLY DISCUSSION
+
+When planning a kernel development project, it makes great sense to hold
+discussions with the community before launching into implementation.  Early
+communication can save time and trouble in a number of ways:
+
+ - It may well be that the problem is addressed by the kernel in ways which
+   you have not understood.  The Linux kernel is large and has a number of
+   features and capabilities which are not immediately obvious.  Not all
+   kernel capabilities are documented as well as one might like, and it is
+   easy to miss things.  Your author has seen the posting of a complete
+   driver which duplicated an existing driver that the new author had been
+   unaware of.  Code which reinvents existing wheels is not only wasteful;
+   it will also not be accepted into the mainline kernel.
+
+ - There may be elements of the proposed solution which will not be
+   acceptable for mainline merging.  It is better to find out about
+   problems like this before writing the code.
+
+ - It's entirely possible that other developers have thought about the
+   problem; they may have ideas for a better solution, and may be willing
+   to help in the creation of that solution.
+
+Years of experience with the kernel development community have taught a
+clear lesson: kernel code which is designed and developed behind closed
+doors invariably has problems which are only revealed when the code is
+released into the community.  Sometimes these problems are severe,
+requiring months or years of effort before the code can be brought up to
+the kernel community's standards.  Some examples include:
+
+ - The Devicescape network stack was designed and implemented for
+   single-processor systems.  It could not be merged into the mainline
+   until it was made suitable for multiprocessor systems.  Retrofitting
+   locking and such into code is a difficult task; as a result, the merging
+   of this code (now called mac80211) was delayed for over a year.
+
+ - The Reiser4 filesystem included a number of capabilities which, in the
+   core kernel developers' opinion, should have been implemented in the
+   virtual filesystem layer instead.  It also included features which could
+   not easily be implemented without exposing the system to user-caused
+   deadlocks.  The late revelation of these problems - and refusal to
+   address some of them - has caused Reiser4 to stay out of the mainline
+   kernel.
+
+ - The AppArmor security module made use of internal virtual filesystem
+   data structures in ways which were considered to be unsafe and
+   unreliable.  This code has since been significantly reworked, but
+   remains outside of the mainline.
+
+In each of these cases, a great deal of pain and extra work could have been
+avoided with some early discussion with the kernel developers.
+
+
+3.3: WHO DO YOU TALK TO?
+
+When developers decide to take their plans public, the next question will
+be: where do we start?  The answer is to find the right mailing list(s) and
+the right maintainer.  For mailing lists, the best approach is to look in
+the MAINTAINERS file for a relevant place to post.  If there is a suitable
+subsystem list, posting there is often preferable to posting on
+linux-kernel; you are more likely to reach developers with expertise in the
+relevant subsystem and the environment may be more supportive.
+
+Finding maintainers can be a bit harder.  Again, the MAINTAINERS file is
+the place to start.  That file tends to not always be up to date, though,
+and not all subsystems are represented there.  The person listed in the
+MAINTAINERS file may, in fact, not be the person who is actually acting in
+that role currently.  So, when there is doubt about who to contact, a
+useful trick is to use git (and "git log" in particular) to see who is
+currently active within the subsystem of interest.  Look at who is writing
+patches, and who, if anybody, is attaching Signed-off-by lines to those
+patches.  Those are the people who will be best placed to help with a new
+development project.
+
+If all else fails, talking to Andrew Morton can be an effective way to
+track down a maintainer for a specific piece of code.
+
+
+3.4: WHEN TO POST?
+
+If possible, posting your plans during the early stages can only be
+helpful.  Describe the problem being solved and any plans that have been
+made on how the implementation will be done.  Any information you can
+provide can help the development community provide useful input on the
+project.
+
+One discouraging thing which can happen at this stage is not a hostile
+reaction, but, instead, little or no reaction at all.  The sad truth of the
+matter is (1) kernel developers tend to be busy, (2) there is no shortage
+of people with grand plans and little code (or even prospect of code) to
+back them up, and (3) nobody is obligated to review or comment on ideas
+posted by others.  If a request-for-comments posting yields little in the
+way of comments, do not assume that it means there is no interest in the
+project.  Unfortunately, you also cannot assume that there are no problems
+with your idea.  The best thing to do in this situation is to proceed,
+keeping the community informed as you go.
+
+
+3.5: GETTING OFFICIAL BUY-IN
+
+If your work is being done in a corporate environment - as most Linux
+kernel work is - you must, obviously, have permission from suitably
+empowered managers before you can post your company's plans or code to a
+public mailing list.  The posting of code which has not been cleared for
+release under a GPL-compatible license can be especially problematic; the
+sooner that a company's management and legal staff can agree on the posting
+of a kernel development project, the better off everybody involved will be.
+
+Some readers may be thinking at this point that their kernel work is
+intended to support a product which does not yet have an officially
+acknowledged existence.  Revealing their employer's plans on a public
+mailing list may not be a viable option.  In cases like this, it is worth
+considering whether the secrecy is really necessary; there is often no real
+need to keep development plans behind closed doors.
+
+That said, there are also cases where a company legitimately cannot
+disclose its plans early in the development process.  Companies with
+experienced kernel developers may choose to proceed in an open-loop manner
+on the assumption that they will be able to avoid serious integration
+problems later.  For companies without that sort of in-house expertise, the
+best option is often to hire an outside developer to review the plans under
+a non-disclosure agreement.  The Linux Foundation operates an NDA program
+designed to help with this sort of situation; more information can be found
+at:
+
+    http://www.linuxfoundation.org/en/NDA_program
+
+This kind of review is often enough to avoid serious problems later on
+without requiring public disclosure of the project.
diff --git a/Documentation/development-process/4.Coding b/Documentation/development-process/4.Coding
new file mode 100644 (file)
index 0000000..014aca8
--- /dev/null
@@ -0,0 +1,384 @@
+4: GETTING THE CODE RIGHT
+
+While there is much to be said for a solid and community-oriented design
+process, the proof of any kernel development project is in the resulting
+code.  It is the code which will be examined by other developers and merged
+(or not) into the mainline tree.  So it is the quality of this code which
+will determine the ultimate success of the project.
+
+This section will examine the coding process.  We'll start with a look at a
+number of ways in which kernel developers can go wrong.  Then the focus
+will shift toward doing things right and the tools which can help in that
+quest.
+
+
+4.1: PITFALLS
+
+* Coding style
+
+The kernel has long had a standard coding style, described in
+Documentation/CodingStyle.  For much of that time, the policies described
+in that file were taken as being, at most, advisory.  As a result, there is
+a substantial amount of code in the kernel which does not meet the coding
+style guidelines.  The presence of that code leads to two independent
+hazards for kernel developers.
+
+The first of these is to believe that the kernel coding standards do not
+matter and are not enforced.  The truth of the matter is that adding new
+code to the kernel is very difficult if that code is not coded according to
+the standard; many developers will request that the code be reformatted
+before they will even review it.  A code base as large as the kernel
+requires some uniformity of code to make it possible for developers to
+quickly understand any part of it.  So there is no longer room for
+strangely-formatted code.
+
+Occasionally, the kernel's coding style will run into conflict with an
+employer's mandated style.  In such cases, the kernel's style will have to
+win before the code can be merged.  Putting code into the kernel means
+giving up a degree of control in a number of ways - including control over
+how the code is formatted.
+
+The other trap is to assume that code which is already in the kernel is
+urgently in need of coding style fixes.  Developers may start to generate
+reformatting patches as a way of gaining familiarity with the process, or
+as a way of getting their name into the kernel changelogs - or both.  But
+pure coding style fixes are seen as noise by the development community;
+they tend to get a chilly reception.  So this type of patch is best
+avoided.  It is natural to fix the style of a piece of code while working
+on it for other reasons, but coding style changes should not be made for
+their own sake.
+
+The coding style document also should not be read as an absolute law which
+can never be transgressed.  If there is a good reason to go against the
+style (a line which becomes far less readable if split to fit within the
+80-column limit, for example), just do it.
+
+
+* Abstraction layers
+
+Computer Science professors teach students to make extensive use of
+abstraction layers in the name of flexibility and information hiding.
+Certainly the kernel makes extensive use of abstraction; no project
+involving several million lines of code could do otherwise and survive.
+But experience has shown that excessive or premature abstraction can be
+just as harmful as premature optimization.  Abstraction should be used to
+the level required and no further.
+
+At a simple level, consider a function which has an argument which is
+always passed as zero by all callers.  One could retain that argument just
+in case somebody eventually needs to use the extra flexibility that it
+provides.  By that time, though, chances are good that the code which
+implements this extra argument has been broken in some subtle way which was
+never noticed - because it has never been used.  Or, when the need for
+extra flexibility arises, it does not do so in a way which matches the
+programmer's early expectation.  Kernel developers will routinely submit
+patches to remove unused arguments; they should, in general, not be added
+in the first place.
+
+Abstraction layers which hide access to hardware - often to allow the bulk
+of a driver to be used with multiple operating systems - are especially
+frowned upon.  Such layers obscure the code and may impose a performance
+penalty; they do not belong in the Linux kernel.
+
+On the other hand, if you find yourself copying significant amounts of code
+from another kernel subsystem, it is time to ask whether it would, in fact,
+make sense to pull out some of that code into a separate library or to
+implement that functionality at a higher level.  There is no value in
+replicating the same code throughout the kernel.
+
+
+* #ifdef and preprocessor use in general
+
+The C preprocessor seems to present a powerful temptation to some C
+programmers, who see it as a way to efficiently encode a great deal of
+flexibility into a source file.  But the preprocessor is not C, and heavy
+use of it results in code which is much harder for others to read and
+harder for the compiler to check for correctness.  Heavy preprocessor use
+is almost always a sign of code which needs some cleanup work.
+
+Conditional compilation with #ifdef is, indeed, a powerful feature, and it
+is used within the kernel.  But there is little desire to see code which is
+sprinkled liberally with #ifdef blocks.  As a general rule, #ifdef use
+should be confined to header files whenever possible.
+Conditionally-compiled code can be confined to functions which, if the code
+is not to be present, simply become empty.  The compiler will then quietly
+optimize out the call to the empty function.  The result is far cleaner
+code which is easier to follow.
+
+C preprocessor macros present a number of hazards, including possible
+multiple evaluation of expressions with side effects and no type safety.
+If you are tempted to define a macro, consider creating an inline function
+instead.  The code which results will be the same, but inline functions are
+easier to read, do not evaluate their arguments multiple times, and allow
+the compiler to perform type checking on the arguments and return value.
+
+
+* Inline functions
+
+Inline functions present a hazard of their own, though.  Programmers can
+become enamored of the perceived efficiency inherent in avoiding a function
+call and fill a source file with inline functions.  Those functions,
+however, can actually reduce performance.  Since their code is replicated
+at each call site, they end up bloating the size of the compiled kernel.
+That, in turn, creates pressure on the processor's memory caches, which can
+slow execution dramatically.  Inline functions, as a rule, should be quite
+small and relatively rare.  The cost of a function call, after all, is not
+that high; the creation of large numbers of inline functions is a classic
+example of premature optimization.
+
+In general, kernel programmers ignore cache effects at their peril.  The
+classic time/space tradeoff taught in beginning data structures classes
+often does not apply to contemporary hardware.  Space *is* time, in that a
+larger program will run slower than one which is more compact.
+
+
+* Locking
+
+In May, 2006, the "Devicescape" networking stack was, with great
+fanfare, released under the GPL and made available for inclusion in the
+mainline kernel.  This donation was welcome news; support for wireless
+networking in Linux was considered substandard at best, and the Devicescape
+stack offered the promise of fixing that situation.  Yet, this code did not
+actually make it into the mainline until June, 2007 (2.6.22).  What
+happened?
+
+This code showed a number of signs of having been developed behind
+corporate doors.  But one large problem in particular was that it was not
+designed to work on multiprocessor systems.  Before this networking stack
+(now called mac80211) could be merged, a locking scheme needed to be
+retrofitted onto it.  
+
+Once upon a time, Linux kernel code could be developed without thinking
+about the concurrency issues presented by multiprocessor systems.  Now,
+however, this document is being written on a dual-core laptop.  Even on
+single-processor systems, work being done to improve responsiveness will
+raise the level of concurrency within the kernel.  The days when kernel
+code could be written without thinking about locking are long past.
+
+Any resource (data structures, hardware registers, etc.) which could be
+accessed concurrently by more than one thread must be protected by a lock.
+New code should be written with this requirement in mind; retrofitting
+locking after the fact is a rather more difficult task.  Kernel developers
+should take the time to understand the available locking primitives well
+enough to pick the right tool for the job.  Code which shows a lack of
+attention to concurrency will have a difficult path into the mainline.
+
+
+* Regressions
+
+One final hazard worth mentioning is this: it can be tempting to make a
+change (which may bring big improvements) which causes something to break
+for existing users.  This kind of change is called a "regression," and
+regressions have become most unwelcome in the mainline kernel.  With few
+exceptions, changes which cause regressions will be backed out if the
+regression cannot be fixed in a timely manner.  Far better to avoid the
+regression in the first place.
+
+It is often argued that a regression can be justified if it causes things
+to work for more people than it creates problems for.  Why not make a
+change if it brings new functionality to ten systems for each one it
+breaks?  The best answer to this question was expressed by Linus in July,
+2007:
+
+       So we don't fix bugs by introducing new problems.  That way lies
+       madness, and nobody ever knows if you actually make any real
+       progress at all. Is it two steps forwards, one step back, or one
+       step forward and two steps back?
+
+(http://lwn.net/Articles/243460/).
+
+An especially unwelcome type of regression is any sort of change to the
+user-space ABI.  Once an interface has been exported to user space, it must
+be supported indefinitely.  This fact makes the creation of user-space
+interfaces particularly challenging: since they cannot be changed in
+incompatible ways, they must be done right the first time.  For this
+reason, a great deal of thought, clear documentation, and wide review for
+user-space interfaces is always required.
+
+
+
+4.2: CODE CHECKING TOOLS
+
+For now, at least, the writing of error-free code remains an ideal that few
+of us can reach.  What we can hope to do, though, is to catch and fix as
+many of those errors as possible before our code goes into the mainline
+kernel.  To that end, the kernel developers have put together an impressive
+array of tools which can catch a wide variety of obscure problems in an
+automated way.  Any problem caught by the computer is a problem which will
+not afflict a user later on, so it stands to reason that the automated
+tools should be used whenever possible.
+
+The first step is simply to heed the warnings produced by the compiler.
+Contemporary versions of gcc can detect (and warn about) a large number of
+potential errors.  Quite often, these warnings point to real problems.
+Code submitted for review should, as a rule, not produce any compiler
+warnings.  When silencing warnings, take care to understand the real cause
+and try to avoid "fixes" which make the warning go away without addressing
+its cause.
+
+Note that not all compiler warnings are enabled by default.  Build the
+kernel with "make EXTRA_CFLAGS=-W" to get the full set.
+
+The kernel provides several configuration options which turn on debugging
+features; most of these are found in the "kernel hacking" submenu.  Several
+of these options should be turned on for any kernel used for development or
+testing purposes.  In particular, you should turn on:
+
+ - ENABLE_WARN_DEPRECATED, ENABLE_MUST_CHECK, and FRAME_WARN to get an
+   extra set of warnings for problems like the use of deprecated interfaces
+   or ignoring an important return value from a function.  The output
+   generated by these warnings can be verbose, but one need not worry about
+   warnings from other parts of the kernel.
+
+ - DEBUG_OBJECTS will add code to track the lifetime of various objects
+   created by the kernel and warn when things are done out of order.  If
+   you are adding a subsystem which creates (and exports) complex objects
+   of its own, consider adding support for the object debugging
+   infrastructure.
+
+ - DEBUG_SLAB can find a variety of memory allocation and use errors; it
+   should be used on most development kernels.
+
+ - DEBUG_SPINLOCK, DEBUG_SPINLOCK_SLEEP, and DEBUG_MUTEXES will find a
+   number of common locking errors.
+
+There are quite a few other debugging options, some of which will be
+discussed below.  Some of them have a significant performance impact and
+should not be used all of the time.  But some time spent learning the
+available options will likely be paid back many times over in short order. 
+
+One of the heavier debugging tools is the locking checker, or "lockdep."
+This tool will track the acquisition and release of every lock (spinlock or
+mutex) in the system, the order in which locks are acquired relative to
+each other, the current interrupt environment, and more.  It can then
+ensure that locks are always acquired in the same order, that the same
+interrupt assumptions apply in all situations, and so on.  In other words,
+lockdep can find a number of scenarios in which the system could, on rare
+occasion, deadlock.  This kind of problem can be painful (for both
+developers and users) in a deployed system; lockdep allows them to be found
+in an automated manner ahead of time.  Code with any sort of non-trivial
+locking should be run with lockdep enabled before being submitted for
+inclusion. 
+
+As a diligent kernel programmer, you will, beyond doubt, check the return
+status of any operation (such as a memory allocation) which can fail.  The
+fact of the matter, though, is that the resulting failure recovery paths
+are, probably, completely untested.  Untested code tends to be broken code;
+you could be much more confident of your code if all those error-handling
+paths had been exercised a few times.
+
+The kernel provides a fault injection framework which can do exactly that,
+especially where memory allocations are involved.  With fault injection
+enabled, a configurable percentage of memory allocations will be made to
+fail; these failures can be restricted to a specific range of code.
+Running with fault injection enabled allows the programmer to see how the
+code responds when things go badly.  See
+Documentation/fault-injection/fault-injection.text for more information on
+how to use this facility.
+
+Other kinds of errors can be found with the "sparse" static analysis tool.
+With sparse, the programmer can be warned about confusion between
+user-space and kernel-space addresses, mixture of big-endian and
+small-endian quantities, the passing of integer values where a set of bit
+flags is expected, and so on.  Sparse must be installed separately (it can
+be found at http://www.kernel.org/pub/software/devel/sparse/ if your
+distributor does not package it); it can then be run on the code by adding
+"C=1" to your make command.
+
+Other kinds of portability errors are best found by compiling your code for
+other architectures.  If you do not happen to have an S/390 system or a
+Blackfin development board handy, you can still perform the compilation
+step.  A large set of cross compilers for x86 systems can be found at 
+
+       http://www.kernel.org/pub/tools/crosstool/
+
+Some time spent installing and using these compilers will help avoid
+embarrassment later.
+
+
+4.3: DOCUMENTATION
+
+Documentation has often been more the exception than the rule with kernel
+development.  Even so, adequate documentation will help to ease the merging
+of new code into the kernel, make life easier for other developers, and
+will be helpful for your users.  In many cases, the addition of
+documentation has become essentially mandatory.
+
+The first piece of documentation for any patch is its associated
+changelog.  Log entries should describe the problem being solved, the form
+of the solution, the people who worked on the patch, any relevant
+effects on performance, and anything else that might be needed to
+understand the patch.
+
+Any code which adds a new user-space interface - including new sysfs or
+/proc files - should include documentation of that interface which enables
+user-space developers to know what they are working with.  See
+Documentation/ABI/README for a description of how this documentation should
+be formatted and what information needs to be provided.
+
+The file Documentation/kernel-parameters.txt describes all of the kernel's
+boot-time parameters.  Any patch which adds new parameters should add the
+appropriate entries to this file.
+
+Any new configuration options must be accompanied by help text which
+clearly explains the options and when the user might want to select them. 
+
+Internal API information for many subsystems is documented by way of
+specially-formatted comments; these comments can be extracted and formatted
+in a number of ways by the "kernel-doc" script.  If you are working within
+a subsystem which has kerneldoc comments, you should maintain them and add
+them, as appropriate, for externally-available functions.  Even in areas
+which have not been so documented, there is no harm in adding kerneldoc
+comments for the future; indeed, this can be a useful activity for
+beginning kernel developers.  The format of these comments, along with some
+information on how to create kerneldoc templates can be found in the file
+Documentation/kernel-doc-nano-HOWTO.txt.
+
+Anybody who reads through a significant amount of existing kernel code will
+note that, often, comments are most notable by their absence.  Once again,
+the expectations for new code are higher than they were in the past;
+merging uncommented code will be harder.  That said, there is little desire
+for verbosely-commented code.  The code should, itself, be readable, with
+comments explaining the more subtle aspects.
+
+Certain things should always be commented.  Uses of memory barriers should
+be accompanied by a line explaining why the barrier is necessary.  The
+locking rules for data structures generally need to be explained somewhere.
+Major data structures need comprehensive documentation in general.
+Non-obvious dependencies between separate bits of code should be pointed
+out.  Anything which might tempt a code janitor to make an incorrect
+"cleanup" needs a comment saying why it is done the way it is.  And so on.
+
+
+4.4: INTERNAL API CHANGES
+
+The binary interface provided by the kernel to user space cannot be broken
+except under the most severe circumstances.  The kernel's internal
+programming interfaces, instead, are highly fluid and can be changed when
+the need arises.  If you find yourself having to work around a kernel API,
+or simply not using a specific functionality because it does not meet your
+needs, that may be a sign that the API needs to change.  As a kernel
+developer, you are empowered to make such changes.
+
+There are, of course, some catches.  API changes can be made, but they need
+to be well justified.  So any patch making an internal API change should be
+accompanied by a description of what the change is and why it is
+necessary.  This kind of change should also be broken out into a separate
+patch, rather than buried within a larger patch.
+
+The other catch is that a developer who changes an internal API is
+generally charged with the task of fixing any code within the kernel tree
+which is broken by the change.  For a widely-used function, this duty can
+lead to literally hundreds or thousands of changes - many of which are
+likely to conflict with work being done by other developers.  Needless to
+say, this can be a large job, so it is best to be sure that the
+justification is solid.
+
+When making an incompatible API change, one should, whenever possible,
+ensure that code which has not been updated is caught by the compiler.  
+This will help you to be sure that you have found all in-tree uses of that
+interface.  It will also alert developers of out-of-tree code that there is
+a change that they need to respond to.  Supporting out-of-tree code is not
+something that kernel developers need to be worried about, but we also do
+not have to make life harder for out-of-tree developers than it it needs to
+be. 
diff --git a/Documentation/development-process/5.Posting b/Documentation/development-process/5.Posting
new file mode 100644 (file)
index 0000000..dd48132
--- /dev/null
@@ -0,0 +1,278 @@
+5: POSTING PATCHES
+
+Sooner or later, the time comes when your work is ready to be presented to
+the community for review and, eventually, inclusion into the mainline
+kernel.  Unsurprisingly, the kernel development community has evolved a set
+of conventions and procedures which are used in the posting of patches;
+following them will make life much easier for everybody involved.  This
+document will attempt to cover these expectations in reasonable detail;
+more information can also be found in the files SubmittingPatches,
+SubmittingDrivers, and SubmitChecklist in the kernel documentation
+directory.
+
+
+5.1: WHEN TO POST
+
+There is a constant temptation to avoid posting patches before they are
+completely "ready."  For simple patches, that is not a problem.  If the
+work being done is complex, though, there is a lot to be gained by getting
+feedback from the community before the work is complete.  So you should
+consider posting in-progress work, or even making a git tree available so
+that interested developers can catch up with your work at any time.
+
+When posting code which is not yet considered ready for inclusion, it is a
+good idea to say so in the posting itself.  Also mention any major work
+which remains to be done and any known problems.  Fewer people will look at
+patches which are known to be half-baked, but those who do will come in
+with the idea that they can help you drive the work in the right direction.
+
+
+5.2: BEFORE CREATING PATCHES
+
+There are a number of things which should be done before you consider
+sending patches to the development community.  These include:
+
+ - Test the code to the extent that you can.  Make use of the kernel's
+   debugging tools, ensure that the kernel will build with all reasonable
+   combinations of configuration options, use cross-compilers to build for
+   different architectures, etc.
+
+ - Make sure your code is compliant with the kernel coding style
+   guidelines.
+
+ - Does your change have performance implications?  If so, you should run
+   benchmarks showing what the impact (or benefit) of your change is; a
+   summary of the results should be included with the patch.
+
+ - Be sure that you have the right to post the code.  If this work was done
+   for an employer, the employer likely has a right to the work and must be
+   agreeable with its release under the GPL.
+
+As a general rule, putting in some extra thought before posting code almost
+always pays back the effort in short order.
+
+
+5.3: PATCH PREPARATION
+
+The preparation of patches for posting can be a surprising amount of work,
+but, once again, attempting to save time here is not generally advisable
+even in the short term.
+
+Patches must be prepared against a specific version of the kernel.  As a
+general rule, a patch should be based on the current mainline as found in
+Linus's git tree.  It may become necessary to make versions against -mm,
+linux-next, or a subsystem tree, though, to facilitate wider testing and
+review.  Depending on the area of your patch and what is going on
+elsewhere, basing a patch against these other trees can require a
+significant amount of work resolving conflicts and dealing with API
+changes.
+
+Only the most simple changes should be formatted as a single patch;
+everything else should be made as a logical series of changes.  Splitting
+up patches is a bit of an art; some developers spend a long time figuring
+out how to do it in the way that the community expects.  There are a few
+rules of thumb, however, which can help considerably:
+
+ - The patch series you post will almost certainly not be the series of
+   changes found in your working revision control system.  Instead, the
+   changes you have made need to be considered in their final form, then
+   split apart in ways which make sense.  The developers are interested in
+   discrete, self-contained changes, not the path you took to get to those
+   changes.
+
+ - Each logically independent change should be formatted as a separate
+   patch.  These changes can be small ("add a field to this structure") or
+   large (adding a significant new driver, for example), but they should be
+   conceptually small and amenable to a one-line description.  Each patch
+   should make a specific change which can be reviewed on its own and
+   verified to do what it says it does.
+
+ - As a way of restating the guideline above: do not mix different types of
+   changes in the same patch.  If a single patch fixes a critical security
+   bug, rearranges a few structures, and reformats the code, there is a
+   good chance that it will be passed over and the important fix will be
+   lost.
+
+ - Each patch should yield a kernel which builds and runs properly; if your
+   patch series is interrupted in the middle, the result should still be a
+   working kernel.  Partial application of a patch series is a common
+   scenario when the "git bisect" tool is used to find regressions; if the
+   result is a broken kernel, you will make life harder for developers and
+   users who are engaging in the noble work of tracking down problems.
+
+ - Do not overdo it, though.  One developer recently posted a set of edits
+   to a single file as 500 separate patches - an act which did not make him
+   the most popular person on the kernel mailing list.  A single patch can
+   be reasonably large as long as it still contains a single *logical*
+   change. 
+
+ - It can be tempting to add a whole new infrastructure with a series of
+   patches, but to leave that infrastructure unused until the final patch
+   in the series enables the whole thing.  This temptation should be
+   avoided if possible; if that series adds regressions, bisection will
+   finger the last patch as the one which caused the problem, even though
+   the real bug is elsewhere.  Whenever possible, a patch which adds new
+   code should make that code active immediately.
+
+Working to create the perfect patch series can be a frustrating process
+which takes quite a bit of time and thought after the "real work" has been
+done.  When done properly, though, it is time well spent.
+
+
+5.4: PATCH FORMATTING
+
+So now you have a perfect series of patches for posting, but the work is
+not done quite yet.  Each patch needs to be formatted into a message which
+quickly and clearly communicates its purpose to the rest of the world.  To
+that end, each patch will be composed of the following:
+
+ - An optional "From" line naming the author of the patch.  This line is
+   only necessary if you are passing on somebody else's patch via email,
+   but it never hurts to add it when in doubt.
+
+ - A one-line description of what the patch does.  This message should be
+   enough for a reader who sees it with no other context to figure out the
+   scope of the patch; it is the line that will show up in the "short form"
+   changelogs.  This message is usually formatted with the relevant
+   subsystem name first, followed by the purpose of the patch.  For
+   example:
+
+       gpio: fix build on CONFIG_GPIO_SYSFS=n
+
+ - A blank line followed by a detailed description of the contents of the
+   patch.  This description can be as long as is required; it should say
+   what the patch does and why it should be applied to the kernel.
+
+ - One or more tag lines, with, at a minimum, one Signed-off-by: line from
+   the author of the patch.  Tags will be described in more detail below.
+
+The above three items should, normally, be the text used when committing
+the change to a revision control system.  They are followed by:
+
+ - The patch itself, in the unified ("-u") patch format.  Using the "-p"
+   option to diff will associate function names with changes, making the
+   resulting patch easier for others to read.
+
+You should avoid including changes to irrelevant files (those generated by
+the build process, for example, or editor backup files) in the patch.  The
+file "dontdiff" in the Documentation directory can help in this regard;
+pass it to diff with the "-X" option.
+
+The tags mentioned above are used to describe how various developers have
+been associated with the development of this patch.  They are described in
+detail in the SubmittingPatches document; what follows here is a brief
+summary.  Each of these lines has the format:
+
+       tag: Full Name <email address>  optional-other-stuff
+
+The tags in common use are:
+
+ - Signed-off-by: this is a developer's certification that he or she has
+   the right to submit the patch for inclusion into the kernel.  It is an
+   agreement to the Developer's Certificate of Origin, the full text of
+   which can be found in Documentation/SubmittingPatches.  Code without a
+   proper signoff cannot be merged into the mainline.
+
+ - Acked-by: indicates an agreement by another developer (often a
+   maintainer of the relevant code) that the patch is appropriate for
+   inclusion into the kernel.
+
+ - Tested-by: states that the named person has tested the patch and found
+   it to work.
+
+ - Reviewed-by: the named developer has reviewed the patch for correctness;
+   see the reviewer's statement in Documentation/SubmittingPatches for more
+   detail.
+
+ - Reported-by: names a user who reported a problem which is fixed by this
+   patch; this tag is used to give credit to the (often underappreciated)
+   people who test our code and let us know when things do not work
+   correctly.
+
+ - Cc: the named person received a copy of the patch and had the
+   opportunity to comment on it.
+
+Be careful in the addition of tags to your patches: only Cc: is appropriate
+for addition without the explicit permission of the person named.
+
+
+5.5: SENDING THE PATCH
+
+Before you mail your patches, there are a couple of other things you should
+take care of:
+
+ - Are you sure that your mailer will not corrupt the patches?  Patches
+   which have had gratuitous white-space changes or line wrapping performed
+   by the mail client will not apply at the other end, and often will not
+   be examined in any detail.  If there is any doubt at all, mail the patch
+   to yourself and convince yourself that it shows up intact.  
+
+   Documentation/email-clients.txt has some helpful hints on making
+   specific mail clients work for sending patches.
+
+ - Are you sure your patch is free of silly mistakes?  You should always
+   run patches through scripts/checkpatch.pl and address the complaints it
+   comes up with.  Please bear in mind that checkpatch.pl, while being the
+   embodiment of a fair amount of thought about what kernel patches should
+   look like, is not smarter than you.  If fixing a checkpatch.pl complaint
+   would make the code worse, don't do it.
+
+Patches should always be sent as plain text.  Please do not send them as
+attachments; that makes it much harder for reviewers to quote sections of
+the patch in their replies.  Instead, just put the patch directly into your
+message.
+
+When mailing patches, it is important to send copies to anybody who might
+be interested in it.  Unlike some other projects, the kernel encourages
+people to err on the side of sending too many copies; don't assume that the
+relevant people will see your posting on the mailing lists.  In particular,
+copies should go to:
+
+ - The maintainer(s) of the affected subsystem(s).  As described earlier,
+   the MAINTAINERS file is the first place to look for these people.
+
+ - Other developers who have been working in the same area - especially
+   those who might be working there now.  Using git to see who else has
+   modified the files you are working on can be helpful.
+
+ - If you are responding to a bug report or a feature request, copy the
+   original poster as well.
+
+ - Send a copy to the relevant mailing list, or, if nothing else applies,
+   the linux-kernel list.
+
+ - If you are fixing a bug, think about whether the fix should go into the
+   next stable update.  If so, stable@kernel.org should get a copy of the
+   patch.  Also add a "Cc: stable@kernel.org" to the tags within the patch
+   itself; that will cause the stable team to get a notification when your
+   fix goes into the mainline.
+
+When selecting recipients for a patch, it is good to have an idea of who
+you think will eventually accept the patch and get it merged.  While it
+is possible to send patches directly to Linus Torvalds and have him merge
+them, things are not normally done that way.  Linus is busy, and there are
+subsystem maintainers who watch over specific parts of the kernel.  Usually
+you will be wanting that maintainer to merge your patches.  If there is no
+obvious maintainer, Andrew Morton is often the patch target of last resort.
+
+Patches need good subject lines.  The canonical format for a patch line is
+something like:
+
+       [PATCH nn/mm] subsys: one-line description of the patch
+
+where "nn" is the ordinal number of the patch, "mm" is the total number of
+patches in the series, and "subsys" is the name of the affected subsystem.
+Clearly, nn/mm can be omitted for a single, standalone patch.  
+
+If you have a significant series of patches, it is customary to send an
+introductory description as part zero.  This convention is not universally
+followed though; if you use it, remember that information in the
+introduction does not make it into the kernel changelogs.  So please ensure
+that the patches, themselves, have complete changelog information.
+
+In general, the second and following parts of a multi-part patch should be
+sent as a reply to the first part so that they all thread together at the
+receiving end.  Tools like git and quilt have commands to mail out a set of
+patches with the proper threading.  If you have a long series, though, and
+are using git, please provide the --no-chain-reply-to option to avoid
+creating exceptionally deep nesting.
diff --git a/Documentation/development-process/6.Followthrough b/Documentation/development-process/6.Followthrough
new file mode 100644 (file)
index 0000000..a8fba3d
--- /dev/null
@@ -0,0 +1,202 @@
+6: FOLLOWTHROUGH
+
+At this point, you have followed the guidelines given so far and, with the
+addition of your own engineering skills, have posted a perfect series of
+patches.  One of the biggest mistakes that even experienced kernel
+developers can make is to conclude that their work is now done.  In truth,
+posting patches indicates a transition into the next stage of the process,
+with, possibly, quite a bit of work yet to be done.
+
+It is a rare patch which is so good at its first posting that there is no
+room for improvement.  The kernel development process recognizes this fact,
+and, as a result, is heavily oriented toward the improvement of posted
+code.  You, as the author of that code, will be expected to work with the
+kernel community to ensure that your code is up to the kernel's quality
+standards.  A failure to participate in this process is quite likely to
+prevent the inclusion of your patches into the mainline.
+
+
+6.1: WORKING WITH REVIEWERS
+
+A patch of any significance will result in a number of comments from other
+developers as they review the code.  Working with reviewers can be, for
+many developers, the most intimidating part of the kernel development
+process.  Life can be made much easier, though, if you keep a few things in
+mind:
+
+ - If you have explained your patch well, reviewers will understand its
+   value and why you went to the trouble of writing it.  But that value
+   will not keep them from asking a fundamental question: what will it be
+   like to maintain a kernel with this code in it five or ten years later?
+   Many of the changes you may be asked to make - from coding style tweaks
+   to substantial rewrites - come from the understanding that Linux will
+   still be around and under development a decade from now.
+
+ - Code review is hard work, and it is a relatively thankless occupation;
+   people remember who wrote kernel code, but there is little lasting fame
+   for those who reviewed it.  So reviewers can get grumpy, especially when
+   they see the same mistakes being made over and over again.  If you get a
+   review which seems angry, insulting, or outright offensive, resist the
+   impulse to respond in kind.  Code review is about the code, not about
+   the people, and code reviewers are not attacking you personally.
+
+ - Similarly, code reviewers are not trying to promote their employers'
+   agendas at the expense of your own.  Kernel developers often expect to
+   be working on the kernel years from now, but they understand that their
+   employer could change.  They truly are, almost without exception,
+   working toward the creation of the best kernel they can; they are not
+   trying to create discomfort for their employers' competitors.
+
+What all of this comes down to is that, when reviewers send you comments,
+you need to pay attention to the technical observations that they are
+making.  Do not let their form of expression or your own pride keep that
+from happening.  When you get review comments on a patch, take the time to
+understand what the reviewer is trying to say.  If possible, fix the things
+that the reviewer is asking you to fix.  And respond back to the reviewer:
+thank them, and describe how you will answer their questions.
+
+Note that you do not have to agree with every change suggested by
+reviewers.  If you believe that the reviewer has misunderstood your code,
+explain what is really going on.  If you have a technical objection to a
+suggested change, describe it and justify your solution to the problem.  If
+your explanations make sense, the reviewer will accept them.  Should your
+explanation not prove persuasive, though, especially if others start to
+agree with the reviewer, take some time to think things over again.  It can
+be easy to become blinded by your own solution to a problem to the point
+that you don't realize that something is fundamentally wrong or, perhaps,
+you're not even solving the right problem.
+
+One fatal mistake is to ignore review comments in the hope that they will
+go away.  They will not go away.  If you repost code without having
+responded to the comments you got the time before, you're likely to find
+that your patches go nowhere.
+
+Speaking of reposting code: please bear in mind that reviewers are not
+going to remember all the details of the code you posted the last time
+around.  So it is always a good idea to remind reviewers of previously
+raised issues and how you dealt with them; the patch changelog is a good
+place for this kind of information.  Reviewers should not have to search
+through list archives to familiarize themselves with what was said last
+time; if you help them get a running start, they will be in a better mood
+when they revisit your code.
+
+What if you've tried to do everything right and things still aren't going
+anywhere?  Most technical disagreements can be resolved through discussion,
+but there are times when somebody simply has to make a decision.  If you
+honestly believe that this decision is going against you wrongly, you can
+always try appealing to a higher power.  As of this writing, that higher
+power tends to be Andrew Morton.  Andrew has a great deal of respect in the
+kernel development community; he can often unjam a situation which seems to
+be hopelessly blocked.  Appealing to Andrew should not be done lightly,
+though, and not before all other alternatives have been explored.  And bear
+in mind, of course, that he may not agree with you either.
+
+
+6.2: WHAT HAPPENS NEXT
+
+If a patch is considered to be a good thing to add to the kernel, and once
+most of the review issues have been resolved, the next step is usually
+entry into a subsystem maintainer's tree.  How that works varies from one
+subsystem to the next; each maintainer has his or her own way of doing
+things.  In particular, there may be more than one tree - one, perhaps,
+dedicated to patches planned for the next merge window, and another for
+longer-term work.  
+
+For patches applying to areas for which there is no obvious subsystem tree
+(memory management patches, for example), the default tree often ends up
+being -mm.  Patches which affect multiple subsystems can also end up going
+through the -mm tree.
+
+Inclusion into a subsystem tree can bring a higher level of visibility to a
+patch.  Now other developers working with that tree will get the patch by
+default.  Subsystem trees typically feed into -mm and linux-next as well,
+making their contents visible to the development community as a whole.  At
+this point, there's a good chance that you will get more comments from a
+new set of reviewers; these comments need to be answered as in the previous
+round.
+
+What may also happen at this point, depending on the nature of your patch,
+is that conflicts with work being done by others turn up.  In the worst
+case, heavy patch conflicts can result in some work being put on the back
+burner so that the remaining patches can be worked into shape and merged.
+Other times, conflict resolution will involve working with the other
+developers and, possibly, moving some patches between trees to ensure that
+everything applies cleanly.  This work can be a pain, but count your
+blessings: before the advent of the linux-next tree, these conflicts often
+only turned up during the merge window and had to be addressed in a hurry.
+Now they can be resolved at leisure, before the merge window opens.
+
+Some day, if all goes well, you'll log on and see that your patch has been
+merged into the mainline kernel.  Congratulations!  Once the celebration is
+complete (and you have added yourself to the MAINTAINERS file), though, it
+is worth remembering an important little fact: the job still is not done.
+Merging into the mainline brings its own challenges.
+
+To begin with, the visibility of your patch has increased yet again.  There
+may be a new round of comments from developers who had not been aware of
+the patch before.  It may be tempting to ignore them, since there is no
+longer any question of your code being merged.  Resist that temptation,
+though; you still need to be responsive to developers who have questions or
+suggestions.
+
+More importantly, though: inclusion into the mainline puts your code into
+the hands of a much larger group of testers.  Even if you have contributed
+a driver for hardware which is not yet available, you will be surprised by
+how many people will build your code into their kernels.  And, of course,
+where there are testers, there will be bug reports.
+
+The worst sort of bug reports are regressions.  If your patch causes a
+regression, you'll find an uncomfortable number of eyes upon you;
+regressions need to be fixed as soon as possible.  If you are unwilling or
+unable to fix the regression (and nobody else does it for you), your patch
+will almost certainly be removed during the stabilization period.  Beyond
+negating all of the work you have done to get your patch into the mainline,
+having a patch pulled as the result of a failure to fix a regression could
+well make it harder for you to get work merged in the future.
+
+After any regressions have been dealt with, there may be other, ordinary
+bugs to deal with.  The stabilization period is your best opportunity to
+fix these bugs and ensure that your code's debut in a mainline kernel
+release is as solid as possible.  So, please, answer bug reports, and fix
+the problems if at all possible.  That's what the stabilization period is
+for; you can start creating cool new patches once any problems with the old
+ones have been taken care of.
+
+And don't forget that there are other milestones which may also create bug
+reports: the next mainline stable release, when prominent distributors pick
+up a version of the kernel containing your patch, etc.  Continuing to
+respond to these reports is a matter of basic pride in your work.  If that
+is insufficient motivation, though, it's also worth considering that the
+development community remembers developers who lose interest in their code
+after it's merged.  The next time you post a patch, they will be evaluating
+it with the assumption that you will not be around to maintain it
+afterward.
+
+
+6.3: OTHER THINGS THAT CAN HAPPEN
+
+One day, you may open your mail client and see that somebody has mailed you
+a patch to your code.  That is one of the advantages of having your code
+out there in the open, after all.  If you agree with the patch, you can
+either forward it on to the subsystem maintainer (be sure to include a
+proper From: line so that the attribution is correct, and add a signoff of
+your own), or send an Acked-by: response back and let the original poster
+send it upward.
+
+If you disagree with the patch, send a polite response explaining why.  If
+possible, tell the author what changes need to be made to make the patch
+acceptable to you.  There is a certain resistance to merging patches which
+are opposed by the author and maintainer of the code, but it only goes so
+far.  If you are seen as needlessly blocking good work, those patches will
+eventually flow around you and get into the mainline anyway.  In the Linux
+kernel, nobody has absolute veto power over any code.  Except maybe Linus.
+
+On very rare occasion, you may see something completely different: another
+developer posts a different solution to your problem.  At that point,
+chances are that one of the two patches will not be merged, and "mine was
+here first" is not considered to be a compelling technical argument.  If
+somebody else's patch displaces yours and gets into the mainline, there is
+really only one way to respond: be pleased that your problem got solved and
+get on with your work.  Having one's work shoved aside in this manner can
+be hurtful and discouraging, but the community will remember your reaction
+long after they have forgotten whose patch actually got merged.
diff --git a/Documentation/development-process/7.AdvancedTopics b/Documentation/development-process/7.AdvancedTopics
new file mode 100644 (file)
index 0000000..a2cf740
--- /dev/null
@@ -0,0 +1,173 @@
+7: ADVANCED TOPICS
+
+At this point, hopefully, you have a handle on how the development process
+works.  There is still more to learn, however!  This section will cover a
+number of topics which can be helpful for developers wanting to become a
+regular part of the Linux kernel development process.
+
+7.1: MANAGING PATCHES WITH GIT
+
+The use of distributed version control for the kernel began in early 2002,
+when Linus first started playing with the proprietary BitKeeper
+application.  While BitKeeper was controversial, the approach to software
+version management it embodied most certainly was not.  Distributed version
+control enabled an immediate acceleration of the kernel development
+project.  In current times, there are several free alternatives to
+BitKeeper.  For better or for worse, the kernel project has settled on git
+as its tool of choice.
+
+Managing patches with git can make life much easier for the developer,
+especially as the volume of those patches grows.  Git also has its rough
+edges and poses certain hazards; it is a young and powerful tool which is
+still being civilized by its developers.  This document will not attempt to
+teach the reader how to use git; that would be sufficient material for a
+long document in its own right.  Instead, the focus here will be on how git
+fits into the kernel development process in particular.  Developers who
+wish to come up to speed with git will find more information at:
+
+       http://git.or.cz/
+
+       http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
+
+and on various tutorials found on the web.
+
+The first order of business is to read the above sites and get a solid
+understanding of how git works before trying to use it to make patches
+available to others.  A git-using developer should be able to obtain a copy
+of the mainline repository, explore the revision history, commit changes to
+the tree, use branches, etc.  An understanding of git's tools for the
+rewriting of history (such as rebase) is also useful.  Git comes with its
+own terminology and concepts; a new user of git should know about refs,
+remote branches, the index, fast-forward merges, pushes and pulls, detached
+heads, etc.  It can all be a little intimidating at the outset, but the
+concepts are not that hard to grasp with a bit of study.
+
+Using git to generate patches for submission by email can be a good
+exercise while coming up to speed.
+
+When you are ready to start putting up git trees for others to look at, you
+will, of course, need a server that can be pulled from.  Setting up such a
+server with git-daemon is relatively straightforward if you have a system
+which is accessible to the Internet.  Otherwise, free, public hosting sites
+(Github, for example) are starting to appear on the net.  Established
+developers can get an account on kernel.org, but those are not easy to come
+by; see http://kernel.org/faq/ for more information.
+
+The normal git workflow involves the use of a lot of branches.  Each line
+of development can be separated into a separate "topic branch" and
+maintained independently.  Branches in git are cheap, there is no reason to
+not make free use of them.  And, in any case, you should not do your
+development in any branch which you intend to ask others to pull from.
+Publicly-available branches should be created with care; merge in patches
+from development branches when they are in complete form and ready to go -
+not before.
+
+Git provides some powerful tools which can allow you to rewrite your
+development history.  An inconvenient patch (one which breaks bisection,
+say, or which has some other sort of obvious bug) can be fixed in place or
+made to disappear from the history entirely.  A patch series can be
+rewritten as if it had been written on top of today's mainline, even though
+you have been working on it for months.  Changes can be transparently
+shifted from one branch to another.  And so on.  Judicious use of git's
+ability to revise history can help in the creation of clean patch sets with
+fewer problems.
+
+Excessive use of this capability can lead to other problems, though, beyond
+a simple obsession for the creation of the perfect project history.
+Rewriting history will rewrite the changes contained in that history,
+turning a tested (hopefully) kernel tree into an untested one.  But, beyond
+that, developers cannot easily collaborate if they do not have a shared
+view of the project history; if you rewrite history which other developers
+have pulled into their repositories, you will make life much more difficult
+for those developers.  So a simple rule of thumb applies here: history
+which has been exported to others should generally be seen as immutable
+thereafter.
+
+So, once you push a set of changes to your publicly-available server, those
+changes should not be rewritten.  Git will attempt to enforce this rule if
+you try to push changes which do not result in a fast-forward merge
+(i.e. changes which do not share the same history).  It is possible to
+override this check, and there may be times when it is necessary to rewrite
+an exported tree.  Moving changesets between trees to avoid conflicts in
+linux-next is one example.  But such actions should be rare.  This is one
+of the reasons why development should be done in private branches (which
+can be rewritten if necessary) and only moved into public branches when
+it's in a reasonably advanced state.
+
+As the mainline (or other tree upon which a set of changes is based)
+advances, it is tempting to merge with that tree to stay on the leading
+edge.  For a private branch, rebasing can be an easy way to keep up with
+another tree, but rebasing is not an option once a tree is exported to the
+world.  Once that happens, a full merge must be done.  Merging occasionally
+makes good sense, but overly frequent merges can clutter the history
+needlessly.  Suggested technique in this case is to merge infrequently, and
+generally only at specific release points (such as a mainline -rc
+release).  If you are nervous about specific changes, you can always
+perform test merges in a private branch.  The git "rerere" tool can be
+useful in such situations; it remembers how merge conflicts were resolved
+so that you don't have to do the same work twice.
+
+One of the biggest recurring complaints about tools like git is this: the
+mass movement of patches from one repository to another makes it easy to
+slip in ill-advised changes which go into the mainline below the review
+radar.  Kernel developers tend to get unhappy when they see that kind of
+thing happening; putting up a git tree with unreviewed or off-topic patches
+can affect your ability to get trees pulled in the future.  Quoting Linus:
+
+       You can send me patches, but for me to pull a git patch from you, I
+       need to know that you know what you're doing, and I need to be able
+       to trust things *without* then having to go and check every
+       individual change by hand.
+
+(http://lwn.net/Articles/224135/).  
+
+To avoid this kind of situation, ensure that all patches within a given
+branch stick closely to the associated topic; a "driver fixes" branch
+should not be making changes to the core memory management code.  And, most
+importantly, do not use a git tree to bypass the review process.  Post an
+occasional summary of the tree to the relevant list, and, when the time is
+right, request that the tree be included in linux-next.
+
+If and when others start to send patches for inclusion into your tree,
+don't forget to review them.  Also ensure that you maintain the correct
+authorship information; the git "am" tool does its best in this regard, but
+you may have to add a "From:" line to the patch if it has been relayed to
+you via a third party.
+
+When requesting a pull, be sure to give all the relevant information: where
+your tree is, what branch to pull, and what changes will result from the
+pull.  The git request-pull command can be helpful in this regard; it will
+format the request as other developers expect, and will also check to be
+sure that you have remembered to push those changes to the public server. 
+
+
+7.2: REVIEWING PATCHES
+
+Some readers will certainly object to putting this section with "advanced
+topics" on the grounds that even beginning kernel developers should be
+reviewing patches.  It is certainly true that there is no better way to
+learn how to program in the kernel environment than by looking at code
+posted by others.  In addition, reviewers are forever in short supply; by
+looking at code you can make a significant contribution to the process as a
+whole.
+
+Reviewing code can be an intimidating prospect, especially for a new kernel
+developer who may well feel nervous about questioning code - in public -
+which has been posted by those with more experience.  Even code written by
+the most experienced developers can be improved, though.  Perhaps the best
+piece of advice for reviewers (all reviewers) is this: phrase review
+comments as questions rather than criticisms.  Asking "how does the lock
+get released in this path?" will always work better than stating "the
+locking here is wrong."
+
+Different developers will review code from different points of view.  Some
+are mostly concerned with coding style and whether code lines have trailing
+white space.  Others will focus primarily on whether the change implemented
+by the patch as a whole is a good thing for the kernel or not.  Yet others
+will check for problematic locking, excessive stack usage, possible
+security issues, duplication of code found elsewhere, adequate
+documentation, adverse effects on performance, user-space ABI changes, etc.
+All types of review, if they lead to better code going into the kernel, are
+welcome and worthwhile.
+
+
diff --git a/Documentation/development-process/8.Conclusion b/Documentation/development-process/8.Conclusion
new file mode 100644 (file)
index 0000000..1990ab4
--- /dev/null
@@ -0,0 +1,74 @@
+8: FOR MORE INFORMATION
+
+There are numerous sources of information on Linux kernel development and
+related topics.  First among those will always be the Documentation
+directory found in the kernel source distribution.  The top-level HOWTO
+file is an important starting point; SubmittingPatches and
+SubmittingDrivers are also something which all kernel developers should
+read.  Many internal kernel APIs are documented using the kerneldoc
+mechanism; "make htmldocs" or "make pdfdocs" can be used to generate those
+documents in HTML or PDF format (though the version of TeX shipped by some
+distributions runs into internal limits and fails to process the documents
+properly).
+
+Various web sites discuss kernel development at all levels of detail.  Your
+author would like to humbly suggest http://lwn.net/ as a source;
+information on many specific kernel topics can be found via the LWN kernel
+index at:
+
+       http://lwn.net/Kernel/Index/
+
+Beyond that, a valuable resource for kernel developers is:
+
+       http://kernelnewbies.org/
+
+Information about the linux-next tree gathers at:
+
+       http://linux.f-seidel.de/linux-next/pmwiki/
+
+And, of course, one should not forget http://kernel.org/, the definitive
+location for kernel release information.
+
+There are a number of books on kernel development:
+
+       Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro
+       Rubini, and Greg Kroah-Hartman).  Online at
+       http://lwn.net/Kernel/LDD3/.
+
+       Linux Kernel Development (Robert Love).
+
+       Understanding the Linux Kernel (Daniel Bovet and Marco Cesati).
+
+All of these books suffer from a common fault, though: they tend to be
+somewhat obsolete by the time they hit the shelves, and they have been on
+the shelves for a while now.  Still, there is quite a bit of good
+information to be found there.
+
+Documentation for git can be found at:
+
+       http://www.kernel.org/pub/software/scm/git/docs/
+
+       http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
+
+
+9: CONCLUSION
+
+Congratulations to anybody who has made it through this long-winded
+document.  Hopefully it has provided a helpful understanding of how the
+Linux kernel is developed and how you can participate in that process.
+
+In the end, it's the participation that matters.  Any open source software
+project is no more than the sum of what its contributors put into it.  The
+Linux kernel has progressed as quickly and as well as it has because it has
+been helped by an impressively large group of developers, all of whom are
+working to make it better.  The kernel is a premier example of what can be
+done when thousands of people work together toward a common goal.
+
+The kernel can always benefit from a larger developer base, though.  There
+is always more work to do.  But, just as importantly, most other
+participants in the Linux ecosystem can benefit through contributing to the
+kernel.  Getting code into the mainline is the key to higher code quality,
+lower maintenance and distribution costs, a higher level of influence over
+the direction of kernel development, and more.  It is a situation where
+everybody involved wins.  Fire up your editor and come join us; you will be
+more than welcome.
index 27809357da58755c4484d711a6bc90534ec07a29..1e89a51ea49b9fa83a8d7cb2d7b61d9eccbfeb25 100644 (file)
@@ -2,11 +2,13 @@
 *.aux
 *.bin
 *.cpio
-*.css
+*.csp
+*.dsp
 *.dvi
+*.elf
 *.eps
-*.fw.gen.S
 *.fw
+*.gen.S
 *.gif
 *.grep
 *.grp
@@ -30,6 +32,7 @@
 *.s
 *.sgml
 *.so
+*.so.dbg
 *.symtypes
 *.tab.c
 *.tab.h
 *.xml
 *_MODULES
 *_vga16.c
-*cscope*
 *~
 *.9
 *.9.gz
 .*
-.cscope
-.gitignore
-.mailmap
 .mm
 53c700_d.h
-53c8xx_d.h*
-COPYING
-CREDITS
 CVS
 ChangeSet
 Image
 Kerntypes
-MODS.txt
+Module.markers
 Module.symvers
 PENDING
 SCCS
@@ -73,7 +69,9 @@ autoconf.h*
 bbootsect
 bin2c
 binkernel.spec
+binoffset
 bootsect
+bounds.h
 bsetup
 btfixupprep
 build
@@ -89,39 +87,36 @@ config_data.h*
 config_data.gz*
 conmakehash
 consolemap_deftbl.c*
+cpustr.h
 crc32table.h*
 cscope.*
-defkeymap.c*
+defkeymap.c
 devlist.h*
 docproc
-dummy_sym.c*
 elf2ecoff
 elfconfig.h*
-filelist
 fixdep
 fore200e_mkfirm
 fore200e_pca_fw.c*
 gconf
 gen-devlist
-gen-kdb_cmds.c*
 gen_crc32table
 gen_init_cpio
 genksyms
-gentbl
 *_gray256.c
+ihex2fw
 ikconfig.h*
 initramfs_data.cpio
 initramfs_data.cpio.gz
 initramfs_list
 kallsyms
 kconfig
-kconfig.tk
-keywords.c*
+keywords.c
 ksym.c*
 ksym.h*
 kxgettext
 lkc_defs.h
-lex.c*
+lex.c
 lex.*.c
 logo_*.c
 logo_*_clut224.c
@@ -130,7 +125,6 @@ lxdialog
 mach-types
 mach-types.h
 machtypes.h
-make_times_h
 map
 maui_boot.h
 mconf
@@ -138,6 +132,7 @@ miboot*
 mk_elfconfig
 mkboot
 mkbugboot
+mkcpustr
 mkdep
 mkprep
 mktables
@@ -145,11 +140,12 @@ mktree
 modpost
 modules.order
 modversions.h*
+ncscope.*
 offset.h
 offsets.h
 oui.c*
-parse.c*
-parse.h*
+parse.c
+parse.h
 patches*
 pca200e.bin
 pca200e_ecd.bin2
@@ -157,7 +153,7 @@ piggy.gz
 piggyback
 pnmtologo
 ppc_defs.h*
-promcon_tbl.c*
+promcon_tbl.c
 pss_boot.h
 qconf
 raid6altivec*.c
@@ -168,27 +164,38 @@ series
 setup
 setup.bin
 setup.elf
-sim710_d.h*
 sImage
 sm_tbl*
 split-include
+syscalltab.h
 tags
 tftpboot.img
 timeconst.h
 times.h*
-tkparse
 trix_boot.h
 utsrelease.h*
+vdso-syms.lds
 vdso.lds
+vdso32-int80-syms.lds
+vdso32-syms.lds
+vdso32-syscall-syms.lds
+vdso32-sysenter-syms.lds
+vdso32.lds
+vdso32.so.dbg
+vdso64.lds
+vdso64.so.dbg
 version.h*
 vmlinux
 vmlinux-*
 vmlinux.aout
-vmlinux*.lds*
-vmlinux*.scr
+vmlinux.lds
 vsyscall.lds
+vsyscall_32.lds
 wanxlfw.inc
 uImage
 unifdef
+wakeup.bin
+wakeup.elf
+wakeup.lds
 zImage*
 zconf.hash.c
index 27a3160650a468bed78a1483d485e1ccbf51bd6d..dd9e944ea6283c7e7e1f321458f94affedfdbdd2 100644 (file)
@@ -14,6 +14,7 @@ graphics devices.  These would include:
        Intel 915GM
        Intel 945G
        Intel 945GM
+       Intel 945GME
        Intel 965G
        Intel 965GM
 
index bcfc233a0080d53146c77f57ee1c96eac7e5e6a4..7ac3c4078ff956985254535c4cc9177519bec05e 100644 (file)
@@ -52,7 +52,7 @@ are either given on the kernel command line or as module parameters, e.g.:
 
  video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
 
- # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap  (module)
+ # modprobe uvesafb mode_option=1024x768-32 mtrr=3 scroll=ywrap  (module)
 
 Accepted options:
 
@@ -105,7 +105,7 @@ vtotal:n
 <mode>  The mode you want to set, in the standard modedb format.  Refer to
         modedb.txt for a detailed description.  When uvesafb is compiled as
         a module, the mode string should be provided as a value of the
-        'mode' option.
+        'mode_option' option.
 
 vbemode:x
         Force the use of VBE mode x.  The mode will only be set if it's
diff --git a/Documentation/fb/viafb.modes b/Documentation/fb/viafb.modes
new file mode 100644 (file)
index 0000000..02e5b48
--- /dev/null
@@ -0,0 +1,870 @@
+#
+#
+#   These data are based on the CRTC parameters in
+#
+#       VIA Integration Graphics Chip
+#       (C) 2004 VIA Technologies Inc.
+#
+
+#
+#   640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      640     480
+#   Scan Frequency      31.469 kHz  59.94 Hz
+#   Sync Width      3.813 us    0.064 ms
+#               12 chars    2 lines
+#   Front Porch     0.636 us    0.318  ms
+#               2 chars     10 lines
+#   Back Porch      1.907 us    1.048  ms
+#               6 chars     33 lines
+#   Active Time     25.422 us   15.253 ms
+#               80 chars    480 lines
+#   Blank Time      6.356 us    1.430 ms
+#               20 chars    45 lines
+#   Polarity        negative    negative
+#
+
+mode "640x480-60"
+# D: 25.175 MHz, H: 31.469 kHz, V: 59.94 Hz
+    geometry 640 480 640 480 32
+    timings 39722 48 16 33 10 96 2 endmode mode "480x640-60"
+# D: 24.823 MHz, H: 39.780 kHz, V: 60.00 Hz
+    geometry 480 640 480 640 32 timings 39722 72 24 19 1 48 3 endmode
+#
+#   640x480, 75 Hz, Non-Interlaced (31.50 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      640     480
+#   Scan Frequency      37.500 kHz  75.00 Hz
+#   Sync Width      2.032 us    0.080 ms
+#               8 chars     3 lines
+#   Front Porch     0.508 us    0.027 ms
+#               2 chars     1 lines
+#   Back Porch      3.810 us    0.427 ms
+#               15 chars    16 lines
+#   Active Time     20.317 us   12.800 ms
+#               80 chars    480 lines
+#   Blank Time      6.349 us    0.533 ms
+#               25 chars    20 lines
+#   Polarity        negative    negative
+#
+    mode "640x480-75"
+# D: 31.50 MHz, H: 37.500 kHz, V: 75.00 Hz
+    geometry 640 480 640 480 32 timings 31747 120 16 16 1 64 3 endmode
+#
+#   640x480, 85 Hz, Non-Interlaced (36.000 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      640     480
+#   Scan Frequency  43.269 kHz  85.00 Hz
+#   Sync Width      1.556 us    0.069 ms
+#               7 chars     3 lines
+#   Front Porch     1.556 us    0.023 ms
+#               7 chars     1 lines
+#   Back Porch      2.222 us    0.578 ms
+#               10 chars    25 lines
+#   Active Time     17.778 us   11.093 ms
+#               80 chars    480 lines
+#   Blank Time      5.333 us    0.670 ms
+#               24 chars    29 lines
+#   Polarity        negative    negative
+#
+    mode "640x480-85"
+# D: 36.000 MHz, H: 43.269 kHz, V: 85.00 Hz
+    geometry 640 480 640 480 32 timings 27777 80 56 25 1 56 3 endmode
+#
+#   640x480, 100 Hz, Non-Interlaced (43.163 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      640     480
+#   Scan Frequency      50.900 kHz  100.00 Hz
+#   Sync Width      1.483 us    0.058 ms
+#               8 chars     3 lines
+#   Front Porch     0.927 us    0.019 ms
+#               5 chars     1 lines
+#   Back Porch      2.409 us    0.475 ms
+#               13 chars    25 lines
+#   Active Time     14.827 us   9.430 ms
+#               80 chars    480 lines
+#   Blank Time      4.819 us    0.570 ms
+#               26 chars    29 lines
+#   Polarity        positive    positive
+#
+    mode "640x480-100"
+# D: 43.163 MHz, H: 50.900 kHz, V: 100.00 Hz
+    geometry 640 480 640 480 32 timings 23168 104 40 25 1 64 3 endmode
+#
+#   640x480, 120 Hz, Non-Interlaced (52.406 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      640     480
+#   Scan Frequency      61.800 kHz  120.00 Hz
+#   Sync Width      1.221 us    0.048 ms
+#               8 chars         3 lines
+#   Front Porch     0.763 us    0.016 ms
+#               5 chars     1 lines
+#   Back Porch      1.984 us    0.496 ms
+#               13 chars    31 lines
+#   Active Time     12.212 us   7.767 ms
+#               80 chars    480 lines
+#   Blank Time      3.969 us    0.566 ms
+#               26 chars    35 lines
+#   Polarity        positive    positive
+#
+    mode "640x480-120"
+# D: 52.406 MHz, H: 61.800 kHz, V: 120.00 Hz
+    geometry 640 480 640 480 32 timings 19081 104 40 31 1 64 3 endmode
+#
+#   720x480, 60 Hz, Non-Interlaced (26.880 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      720     480
+#   Scan Frequency      30.000 kHz  60.241 Hz
+#   Sync Width      2.679 us    0.099 ms
+#               9 chars     3 lines
+#   Front Porch     0.595 us    0.033 ms
+#               2 chars     1 lines
+#   Back Porch      3.274 us    0.462 ms
+#               11 chars    14 lines
+#   Active Time     26.786 us   16.000 ms
+#               90 chars    480 lines
+#   Blank Time      6.548 us    0.600 ms
+#               22 chars    18 lines
+#   Polarity        positive    positive
+#
+    mode "720x480-60"
+# D: 26.880 MHz, H: 30.000 kHz, V: 60.24 Hz
+    geometry 720 480 720 480 32 timings 37202 88 16 14 1 72 3 endmode
+#
+#   800x480, 60 Hz, Non-Interlaced (29.581 MHz dotclock)
+#
+#               Horizontal    Vertical
+#   Resolution      800         480
+#   Scan Frequency  29.892 kHz  60.00 Hz
+#   Sync Width      2.704 us    100.604 us
+#                   10 chars    3 lines
+#   Front Porch     0.541 us    33.535 us
+#                   2 chars     1 lines
+#   Back Porch      3.245 us    435.949 us
+#                   12 chars    13 lines
+#   Active Time     27.044 us   16.097 ms
+#                   100 chars   480 lines
+#   Blank Time      6.491 us    0.570 ms
+#                   24 chars    17 lines
+#   Polarity        positive    positive
+#
+    mode "800x480-60"
+# D: 29.500 MHz, H: 29.738 kHz, V: 60.00 Hz
+    geometry 800 480 800 480 32 timings 33805 96 24 10 3 72 7 endmode
+#
+#   720x576, 60 Hz, Non-Interlaced (32.668 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      720     576
+#   Scan Frequency      35.820 kHz  60.00 Hz
+#   Sync Width      2.204 us    0.083 ms
+#               9 chars     3 lines
+#   Front Porch     0.735 us    0.027 ms
+#               3 chars     1 lines
+#   Back Porch      2.939 us    0.459 ms
+#               12 chars    17 lines
+#   Active Time     22.040 us   16.080 ms
+#               90 chars    476 lines
+#   Blank Time      5.877 us    0.586 ms
+#               24 chars    21 lines
+#   Polarity        positive    positive
+#
+    mode "720x576-60"
+# D: 32.668 MHz, H: 35.820 kHz, V: 60.00 Hz
+    geometry 720 576 720 576 32 timings 30611 96 24 17 1 72 3 endmode
+#
+#   800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      800     600
+#   Scan Frequency      37.879 kHz  60.32 Hz
+#   Sync Width      3.200 us    0.106 ms
+#               16 chars    4 lines
+#   Front Porch     1.000 us    0.026 ms
+#               5 chars     1 lines
+#   Back Porch      2.200 us    0.607 ms
+#               11 chars    23 lines
+#   Active Time     20.000 us   15.840 ms
+#               100 chars   600 lines
+#   Blank Time      6.400 us    0.739 ms
+#               32 chars    28 lines
+#   Polarity        positive    positive
+#
+    mode "800x600-60"
+# D: 40.00 MHz, H: 37.879 kHz, V: 60.32 Hz
+    geometry 800 600 800 600 32
+    timings 25000 88 40 23 1 128 4 hsync high vsync high endmode
+#
+#   800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      800     600
+#   Scan Frequency      46.875 kHz  75.00 Hz
+#   Sync Width      1.616 us    0.064 ms
+#               10 chars    3 lines
+#   Front Porch     0.323 us    0.021 ms
+#               2 chars     1 lines
+#   Back Porch      3.232 us    0.448 ms
+#               20 chars    21 lines
+#   Active Time     16.162 us   12.800 ms
+#               100 chars   600 lines
+#   Blank Time      5.172 us    0.533 ms
+#               32 chars    25 lines
+#   Polarity        positive    positive
+#
+    mode "800x600-75"
+# D: 49.50 MHz, H: 46.875 kHz, V: 75.00 Hz
+    geometry 800 600 800 600 32
+    timings 20203 160 16 21 1 80 3 hsync high vsync high endmode
+#
+#   800x600, 85 Hz, Non-Interlaced (56.25 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      800     600
+#   Scan Frequency      53.674 kHz  85.061 Hz
+#   Sync Width      1.138 us    0.056 ms
+#               8 chars     3 lines
+#   Front Porch     0.569 us    0.019 ms
+#               4 chars     1 lines
+#   Back Porch      2.702 us    0.503 ms
+#               19 chars    27 lines
+#   Active Time     14.222 us   11.179 ms
+#               100 chars   600 lines
+#   Blank Time      4.409 us    0.578 ms
+#               31 chars    31 lines
+#   Polarity        positive    positive
+#
+    mode "800x600-85"
+# D: 56.25 MHz, H: 53.674 kHz, V: 85.061 Hz
+    geometry 800 600 800 600 32
+    timings 17777 152 32 27 1 64 3 hsync high vsync high endmode
+#
+#   800x600, 100 Hz, Non-Interlaced (67.50 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      800     600
+#   Scan Frequency      62.500 kHz  100.00 Hz
+#   Sync Width      0.948 us    0.064 ms
+#               8 chars     4 lines
+#   Front Porch     0.000 us    0.112 ms
+#               0 chars     7 lines
+#   Back Porch      3.200 us    0.224 ms
+#               27 chars    14 lines
+#   Active Time     11.852 us   9.600 ms
+#               100 chars   600 lines
+#   Blank Time      4.148 us    0.400 ms
+#               35 chars    25 lines
+#   Polarity        positive    positive
+#
+    mode "800x600-100"
+# D: 67.50 MHz, H: 62.500 kHz, V: 100.00 Hz
+    geometry 800 600 800 600 32
+    timings 14667 216 0 14 7 64 4 hsync high vsync high endmode
+#
+#   800x600, 120 Hz, Non-Interlaced (83.950 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      800     600
+#   Scan Frequency  77.160 kHz  120.00 Hz
+#   Sync Width      1.048 us    0.039 ms
+#               11 chars    3 lines
+#   Front Porch     0.667 us    0.013 ms
+#               7 chars     1 lines
+#   Back Porch      1.715 us    0.507 ms
+#               18 chars    39 lines
+#   Active Time     9.529 us    7.776 ms
+#               100 chars   600 lines
+#   Blank Time      3.431 us    0.557 ms
+#               36 chars    43 lines
+#   Polarity        positive    positive
+#
+    mode "800x600-120"
+# D: 83.950 MHz, H: 77.160 kHz, V: 120.00 Hz
+    geometry 800 600 800 600 32
+    timings 11912 144 56 39 1 88 3 hsync high vsync high endmode
+#
+#   848x480, 60 Hz, Non-Interlaced (31.490 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      848     480
+#   Scan Frequency  29.820 kHz  60.00 Hz
+#   Sync Width      2.795 us    0.099 ms
+#               11 chars    3 lines
+#   Front Porch     0.508 us    0.033 ms
+#               2 chars     1 lines
+#   Back Porch      3.303 us    0.429 ms
+#               13 chars    13 lines
+#   Active Time     26.929 us   16.097 ms
+#               106 chars   480 lines
+#   Blank Time      6.605 us    0.570 ms
+#               26 chars    17 lines
+#   Polarity        positive    positive
+#
+    mode "848x480-60"
+# D: 31.500 MHz, H: 29.830 kHz, V: 60.00 Hz
+    geometry 848 480 848 480 32
+    timings 31746 104 24 12 3 80 5 hsync high vsync high endmode
+#
+#   856x480, 60 Hz, Non-Interlaced (31.728 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      856     480
+#   Scan Frequency  29.820 kHz  60.00 Hz
+#   Sync Width      2.774 us    0.099 ms
+#               11 chars    3 lines
+#   Front Porch     0.504 us    0.033 ms
+#               2 chars     1 lines
+#   Back Porch      3.728 us    0.429 ms
+#               13 chars    13 lines
+#   Active Time     26.979 us   16.097 ms
+#               107 chars   480 lines
+#   Blank Time      6.556 us    0.570 ms
+#               26 chars    17 lines
+#   Polarity        positive    positive
+#
+    mode "856x480-60"
+# D: 31.728 MHz, H: 29.820 kHz, V: 60.00 Hz
+    geometry 856 480 856 480 32
+    timings 31518 104 16 13 1 88 3
+    hsync high vsync high endmode mode "960x600-60"
+# D: 45.250 MHz, H: 37.212 kHz, V: 60.00 Hz
+    geometry 960 600 960 600 32 timings 22099 128 32 15 3 96 6 endmode
+#
+#   1000x600, 60 Hz, Non-Interlaced (48.068 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1000     600
+#   Scan Frequency  37.320 kHz  60.00 Hz
+#   Sync Width      2.164 us    0.080 ms
+#               13 chars    3 lines
+#   Front Porch     0.832 us    0.027 ms
+#               5 chars     1 lines
+#   Back Porch      2.996 us    0.483 ms
+#               18 chars    18 lines
+#   Active Time     20.804 us   16.077 ms
+#               125 chars   600 lines
+#   Blank Time      5.991 us    0.589 ms
+#               36 chars    22 lines
+#   Polarity        negative    positive
+#
+    mode "1000x600-60"
+# D: 48.068 MHz, H: 37.320 kHz, V: 60.00 Hz
+    geometry 1000 600 1000 600 32
+    timings 20834 144 40 18 1 104 3 endmode mode "1024x576-60"
+# D: 46.996 MHz, H: 35.820 kHz, V: 60.00 Hz
+    geometry 1024 576 1024 576 32
+    timings 21278 144 40 17 1 104 3 endmode mode "1024x600-60"
+# D: 48.964 MHz, H: 37.320 kHz, V: 60.00 Hz
+    geometry 1024 600 1024 600 32
+    timings 20461 144 40 18 1 104 3 endmode mode "1088x612-60"
+# D: 52.952 MHz, H: 38.040 kHz, V: 60.00 Hz
+    geometry 1088 612 1088 612 32 timings 18877 152 48 16 3 104 5 endmode
+#
+#   1024x512, 60 Hz, Non-Interlaced (41.291 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1024    512
+#   Scan Frequency  31.860 kHz  60.00 Hz
+#   Sync Width      2.519 us    0.094 ms
+#               13 chars    3 lines
+#   Front Porch     0.775 us    0.031 ms
+#               4 chars     1 lines
+#   Back Porch      3.294 us    0.465 ms
+#               17 chars    15 lines
+#   Active Time     24.800 us   16.070 ms
+#               128 chars   512 lines
+#   Blank Time      6.587 us    0.596 ms
+#               34 chars    19 lines
+#   Polarity        positive    positive
+#
+    mode "1024x512-60"
+# D: 41.291 MHz, H: 31.860 kHz, V: 60.00 Hz
+    geometry 1024 512 1024 512 32
+    timings 24218 126 32 15 1 104 3 hsync high vsync high endmode
+#
+#   1024x600, 60 Hz, Non-Interlaced (48.875 MHz dotclock)
+#
+#                     Horizontal  Vertical
+#   Resolution          1024        768
+#   Scan Frequency      37.252 kHz  60.00 Hz
+#   Sync Width          2.128 us    80.532us
+#                       13 chars    3 lines
+#   Front Porch        0.818 us     26.844 us
+#                       5 chars     1 lines
+#   Back Porch          2.946 us    483.192 us
+#                       18 chars    18 lines
+#   Active Time         20.951 us   16.697 ms
+#                       128 chars   622 lines
+#   Blank Time          5.893 us    0.591 ms
+#                       36 chars    22 lines
+#   Polarity            negative    positive
+#
+#mode "1024x600-60"
+#     # D: 48.875 MHz, H: 37.252 kHz, V: 60.00 Hz
+#     geometry 1024 600 1024 600 32
+#    timings 20460  144 40 18 1 104  3
+# endmode
+#
+#   1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1024        768
+#   Scan Frequency      48.363 kHz  60.00 Hz
+#   Sync Width      2.092 us    0.124 ms
+#               17 chars    6 lines
+#   Front Porch     0.369 us    0.062 ms
+#               3 chars     3 lines
+#   Back Porch      2.462 us    0.601 ms
+#               20 chars    29 lines
+#   Active Time     15.754 us   15.880 ms
+#               128 chars   768 lines
+#   Blank Time      4.923 us    0.786 ms
+#               40 chars    38 lines
+#   Polarity        negative    negative
+#
+    mode "1024x768-60"
+# D: 65.00 MHz, H: 48.363 kHz, V: 60.00 Hz
+    geometry 1024 768 1024 768 32 timings 15385 160 24 29 3 136 6 endmode
+#
+#   1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1024        768
+#   Scan Frequency      60.023 kHz  75.03 Hz
+#   Sync Width      1.219 us    0.050 ms
+#               12 chars    3 lines
+#   Front Porch     0.203 us    0.017 ms
+#               2 chars     1 lines
+#   Back Porch      2.235 us    0.466 ms
+#               22 chars    28 lines
+#   Active Time     13.003 us   12.795 ms
+#               128 chars   768 lines
+#   Blank Time      3.657 us    0.533 ms
+#               36 chars    32 lines
+#   Polarity        positive    positive
+#
+    mode "1024x768-75"
+# D: 78.75 MHz, H: 60.023 kHz, V: 75.03 Hz
+    geometry 1024 768 1024 768 32
+    timings 12699 176 16 28 1 96 3 hsync high vsync high endmode
+#
+#   1024x768, 85 Hz, Non-Interlaced (94.50 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1024        768
+#   Scan Frequency  68.677 kHz  85.00 Hz
+#   Sync Width      1.016 us    0.044 ms
+#               12 chars    3 lines
+#   Front Porch     0.508 us    0.015 ms
+#               6 chars     1 lines
+#   Back Porch      2.201 us    0.524 ms
+#               26 chars    36 lines
+#   Active Time     10.836 us   11.183 ms
+#               128 chars   768 lines
+#   Blank Time      3.725 us    0.582 ms
+#               44 chars    40 lines
+#   Polarity        positive    positive
+#
+    mode "1024x768-85"
+# D: 94.50 MHz, H: 68.677 kHz, V: 85.00 Hz
+    geometry 1024 768 1024 768 32
+    timings 10582 208 48 36 1 96 3 hsync high vsync high endmode
+#
+#   1024x768, 100 Hz, Non-Interlaced (110.0 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1024        768
+#   Scan Frequency      79.023 kHz  99.78 Hz
+#   Sync Width      0.800 us    0.101 ms
+#               11 chars    8 lines
+#   Front Porch     0.000 us    0.000 ms
+#               0 chars     0 lines
+#   Back Porch      2.545 us    0.202 ms
+#               35 chars    16 lines
+#   Active Time     9.309 us    9.719 ms
+#               128 chars   768 lines
+#   Blank Time      3.345 us    0.304 ms
+#               46 chars    24 lines
+#   Polarity        negative    negative
+#
+    mode "1024x768-100"
+# D: 113.3 MHz, H: 79.023 kHz, V: 99.78 Hz
+    geometry 1024 768 1024 768 32
+    timings 8825 280 0 16 0 88 8 endmode mode "1152x720-60"
+# D: 66.750 MHz, H: 44.859 kHz, V: 60.00 Hz
+    geometry 1152 720 1152 720 32 timings 14981 168 56 19 3 112 6 endmode
+#
+#   1152x864, 75 Hz, Non-Interlaced (110.0 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1152        864
+#   Scan Frequency      75.137 kHz  74.99 Hz
+#   Sync Width      1.309 us    0.106 ms
+#               18 chars    8 lines
+#   Front Porch     0.245 us    0.599 ms
+#               3 chars     45 lines
+#   Back Porch      1.282 us    1.132 ms
+#               18 chars    85 lines
+#   Active Time     10.473 us   11.499 ms
+#               144 chars   864 lines
+#   Blank Time      2.836 us    1.837 ms
+#               39 chars    138 lines
+#   Polarity        positive    positive
+#
+    mode "1152x864-75"
+# D: 110.0 MHz, H: 75.137 kHz, V: 74.99 Hz
+    geometry 1152 864 1152 864 32
+    timings 9259 144 24 85 45 144 8
+    hsync high vsync high endmode mode "1200x720-60"
+# D: 70.184 MHz, H: 44.760 kHz, V: 60.00 Hz
+    geometry 1200 720 1200 720 32
+    timings 14253 184 28 22 1 128 3 endmode mode "1280x600-60"
+# D: 61.503 MHz, H: 37.320 kHz, V: 60.00 Hz
+    geometry 1280 600 1280 600 32
+    timings 16260 184 28 18 1 128 3 endmode mode "1280x720-50"
+# D: 60.466 MHz, H: 37.050 kHz, V: 50.00 Hz
+    geometry 1280 720 1280 720 32
+    timings 16538 176 48 17 1 128 3 endmode mode "1280x768-50"
+# D: 65.178 MHz, H: 39.550 kHz, V: 50.00 Hz
+    geometry 1280 768 1280 768 32 timings 15342 184 28 19 1 128 3 endmode
+#
+#   1280x768, 60 Hz, Non-Interlaced (80.136 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280    768
+#   Scan Frequency  47.700 kHz  60.00 Hz
+#   Sync Width      1.697 us    0.063 ms
+#               17 chars    3 lines
+#   Front Porch     0.799 us    0.021 ms
+#               8 chars     1 lines
+#   Back Porch      2.496 us    0.483 ms
+#               25 chars    23 lines
+#   Active Time     15.973 us   16.101 ms
+#               160 chars   768 lines
+#   Blank Time      4.992 us    0.566 ms
+#               50 chars    27 lines
+#   Polarity        positive    positive
+#
+    mode "1280x768-60"
+# D: 80.13 MHz, H: 47.700 kHz, V: 60.00 Hz
+    geometry 1280 768 1280 768 32
+    timings 12480 200 48 23 1 126 3 hsync high vsync high endmode
+#
+#   1280x800, 60 Hz, Non-Interlaced (83.375 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280    800
+#   Scan Frequency  49.628 kHz  60.00 Hz
+#   Sync Width      1.631 us    60.450 us
+#                   17 chars    3 lines
+#   Front Porch     0.768 us    20.15 us
+#                   8 chars     1 lines
+#   Back Porch      2.399 us    0.483 ms
+#                   25 chars    24 lines
+#   Active Time     15.352 us   16.120 ms
+#                   160 chars   800 lines
+#   Blank Time      4.798 us    0.564 ms
+#                   50 chars    28 lines
+#   Polarity        negtive    positive
+#
+    mode "1280x800-60"
+# D: 83.500 MHz, H: 49.702 kHz, V: 60.00 Hz
+    geometry 1280 800 1280 800 32 timings 11994 200 72 22 3 128 6 endmode
+#
+#   1280x960, 60 Hz, Non-Interlaced (108.00 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280    960
+#   Scan Frequency  60.000 kHz  60.00 Hz
+#   Sync Width      1.037 us    0.050 ms
+#               14 chars    3 lines
+#   Front Porch     0.889 us    0.017 ms
+#               12 chars    1 lines
+#   Back Porch      2.889 us    0.600 ms
+#               39 chars    36 lines
+#   Active Time     11.852 us   16.000 ms
+#               160 chars   960 lines
+#   Blank Time      4.815 us    0.667 ms
+#               65 chars    40 lines
+#   Polarity        positive    positive
+#
+    mode "1280x960-60"
+# D: 108.00 MHz, H: 60.000 kHz, V: 60.00 Hz
+    geometry 1280 960 1280 960 32
+    timings 9259 312 96 36 1 112 3 hsync high vsync high endmode
+#
+#   1280x1024, 60 Hz, Non-Interlaced (108.00 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280        1024
+#   Scan Frequency      63.981 kHz  60.02 Hz
+#   Sync Width      1.037 us    0.047 ms
+#               14 chars    3 lines
+#   Front Porch     0.444 us    0.015 ms
+#               6 chars     1 lines
+#   Back Porch      2.297 us    0.594 ms
+#               31 chars    38 lines
+#   Active Time     11.852 us   16.005 ms
+#               160 chars   1024 lines
+#   Blank Time      3.778 us    0.656 ms
+#               51 chars    42 lines
+#   Polarity        positive    positive
+#
+    mode "1280x1024-60"
+# D: 108.00 MHz, H: 63.981 kHz, V: 60.02 Hz
+    geometry 1280 1024 1280 1024 32
+    timings 9260 248 48 38 1 112 3 hsync high vsync high endmode
+#
+#   1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280        1024
+#   Scan Frequency      79.976 kHz  75.02 Hz
+#   Sync Width      1.067 us    0.038 ms
+#               18 chars    3 lines
+#   Front Porch     0.119 us    0.012 ms
+#               2 chars     1 lines
+#   Back Porch      1.837 us    0.475 ms
+#               31 chars    38 lines
+#   Active Time     9.481 us    12.804 ms
+#               160 chars   1024 lines
+#   Blank Time      3.022 us    0.525 ms
+#               51 chars    42 lines
+#   Polarity        positive    positive
+#
+    mode "1280x1024-75"
+# D: 135.00 MHz, H: 79.976 kHz, V: 75.02 Hz
+    geometry 1280 1024 1280 1024 32
+    timings 7408 248 16 38 1 144 3 hsync high vsync high endmode
+#
+#   1280x1024, 85 Hz, Non-Interlaced (157.50 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280        1024
+#   Scan Frequency  91.146 kHz  85.02 Hz
+#   Sync Width      1.016 us    0.033 ms
+#               20 chars    3 lines
+#   Front Porch     0.406 us    0.011 ms
+#               8 chars     1 lines
+#   Back Porch      1.422 us    0.483 ms
+#               28 chars    44 lines
+#   Active Time     8.127 us    11.235 ms
+#               160 chars   1024 lines
+#   Blank Time      2.844 us    0.527 ms
+#               56 chars    48 lines
+#   Polarity        positive    positive
+#
+    mode "1280x1024-85"
+# D: 157.50 MHz, H: 91.146 kHz, V: 85.02 Hz
+    geometry 1280 1024 1280 1024 32
+    timings 6349 224 64 44 1 160 3
+    hsync high vsync high endmode mode "1440x900-60"
+# D: 106.500 MHz, H: 55.935 kHz, V: 60.00 Hz
+    geometry 1440 900 1440 900 32
+    timings 9390 232 80 25 3 152 6
+    hsync high vsync high endmode mode "1440x900-75"
+# D: 136.750 MHz, H: 70.635 kHz, V: 75.00 Hz
+    geometry 1440 900 1440 900 32
+    timings 7315 248 96 33 3 152 6 hsync high vsync high endmode
+#
+#   1440x1050, 60 Hz, Non-Interlaced (125.10 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1440        1050
+#   Scan Frequency      65.220 kHz  60.00 Hz
+#   Sync Width      1.204 us    0.046 ms
+#               19 chars    3 lines
+#   Front Porch     0.760 us    0.015 ms
+#               12 chars    1 lines
+#   Back Porch      1.964 us    0.495 ms
+#               31 chars    33 lines
+#   Active Time     11.405 us   16.099 ms
+#               180 chars   1050 lines
+#   Blank Time      3.928 us    0.567 ms
+#               62 chars    37 lines
+#   Polarity        positive    positive
+#
+    mode "1440x1050-60"
+# D: 125.10 MHz, H: 65.220 kHz, V: 60.00 Hz
+    geometry 1440 1050 1440 1050 32
+    timings 7993 248 96 33 1 152 3
+    hsync high vsync high endmode mode "1600x900-60"
+# D: 118.250 MHz, H: 55.990 kHz, V: 60.00 Hz
+    geometry 1600 900 1600 900 32
+    timings 8415 256 88 26 3 168 5 endmode mode "1600x1024-60"
+# D: 136.358 MHz, H: 63.600 kHz, V: 60.00 Hz
+    geometry 1600 1024 1600 1024 32 timings 7315 272 104 32 1 168 3 endmode
+#
+#   1600x1200, 60 Hz, Non-Interlaced (156.00 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1600        1200
+#   Scan Frequency      76.200 kHz  60.00 Hz
+#   Sync Width      1.026 us    0.105 ms
+#               20 chars    8 lines
+#   Front Porch     0.205 us    0.131 ms
+#               4 chars     10 lines
+#   Back Porch      1.636 us    0.682 ms
+#               32 chars    52 lines
+#   Active Time     10.256 us   15.748 ms
+#               200 chars   1200 lines
+#   Blank Time      2.872 us    0.866 ms
+#               56 chars    66 lines
+#   Polarity        negative    negative
+#
+    mode "1600x1200-60"
+# D: 156.00 MHz, H: 76.200 kHz, V: 60.00 Hz
+    geometry 1600 1200 1600 1200 32 timings 6172 256 32 52 10 160 8 endmode
+#
+#   1600x1200, 75 Hz, Non-Interlaced (202.50 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1600        1200
+#   Scan Frequency  93.750 kHz  75.00 Hz
+#   Sync Width      0.948 us    0.032 ms
+#               24 chars    3 lines
+#   Front Porch     0.316 us    0.011 ms
+#               8 chars     1 lines
+#   Back Porch      1.501 us    0.491 ms
+#               38 chars    46 lines
+#   Active Time     7.901 us    12.800 ms
+#               200 chars   1200 lines
+#   Blank Time      2.765 us    0.533 ms
+#               70 chars    50 lines
+#   Polarity    positive    positive
+#
+    mode "1600x1200-75"
+# D: 202.50 MHz, H: 93.750 kHz, V: 75.00 Hz
+    geometry 1600 1200 1600 1200 32
+    timings 4938 304 64 46 1 192 3
+    hsync high vsync high endmode mode "1680x1050-60"
+# D: 146.250 MHz, H: 65.290 kHz, V: 59.954 Hz
+    geometry 1680 1050 1680 1050 32
+    timings 6814 280 104 30 3 176 6
+    hsync high vsync high endmode mode "1680x1050-75"
+# D: 187.000 MHz, H: 82.306 kHz, V: 74.892 Hz
+    geometry 1680 1050 1680 1050 32
+    timings 5348 296 120 40 3 176 6
+    hsync high vsync high endmode mode "1792x1344-60"
+# D: 202.975 MHz, H: 83.460 kHz, V: 60.00 Hz
+    geometry 1792 1344 1792 1344 32
+    timings 4902 320 128 43 1 192 3
+    hsync high vsync high endmode mode "1856x1392-60"
+# D: 218.571 MHz, H: 86.460 kHz, V: 60.00 Hz
+    geometry 1856 1392 1856 1392 32
+    timings 4577 336 136 45 1 200 3
+    hsync high vsync high endmode mode "1920x1200-60"
+# D: 193.250 MHz, H: 74.556 kHz, V: 60.00 Hz
+    geometry 1920 1200 1920 1200 32
+    timings 5173 336 136 36 3 200 6
+    hsync high vsync high endmode mode "1920x1440-60"
+# D: 234.000 MHz, H:90.000 kHz, V: 60.00 Hz
+    geometry 1920 1440 1920 1440 32
+    timings 4274 344 128 56 1 208 3
+    hsync high vsync high endmode mode "1920x1440-75"
+# D: 297.000 MHz, H:112.500 kHz, V: 75.00 Hz
+    geometry 1920 1440 1920 1440 32
+    timings 3367 352 144 56 1 224 3
+    hsync high vsync high endmode mode "2048x1536-60"
+# D: 267.250 MHz, H: 95.446 kHz, V: 60.00 Hz
+    geometry 2048 1536 2048 1536 32
+    timings 3742 376 152 49 3 224 4 hsync high vsync high endmode
+#
+#   1280x720, 60 Hz, Non-Interlaced (74.481 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1280        720
+#   Scan Frequency      44.760 kHz  60.00 Hz
+#   Sync Width      1.826 us    67.024 ms
+#               17 chars    3 lines
+#   Front Porch     0.752 us    22.341 ms
+#               7 chars     1 lines
+#   Back Porch      2.578 us    491.510 ms
+#               24 chars    22 lines
+#   Active Time     17.186 us   16.086 ms
+#               160 chars   720 lines
+#   Blank Time      5.156 us    0.581 ms
+#               48 chars    26 lines
+#   Polarity        negative    negative
+#
+    mode "1280x720-60"
+# D: 74.481 MHz, H: 44.760 kHz, V: 60.00 Hz
+    geometry 1280 720 1280 720 32 timings 13426 192 64 22 1 136 3 endmode
+#
+#   1920x1080, 60 Hz, Non-Interlaced (172.798 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1920        1080
+#   Scan Frequency      67.080 kHz  60.00 Hz
+#   Sync Width      1.204 us    44.723 ms
+#               26 chars    3 lines
+#   Front Porch     0.694 us    14.908 ms
+#               15 chars     1 lines
+#   Back Porch      1.898 us    506.857 ms
+#               41 chars    34 lines
+#   Active Time     11.111 us   16.100 ms
+#               240 chars   1080 lines
+#   Blank Time      3.796 us    0.566 ms
+#               82 chars    38 lines
+#   Polarity        negative    negative
+#
+    mode "1920x1080-60"
+# D: 74.481 MHz, H: 67.080 kHz, V: 60.00 Hz
+    geometry 1920 1080 1920 1080 32 timings 5787 328 120 34 1 208 3 endmode
+#
+#   1400x1050, 60 Hz, Non-Interlaced (122.61 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1400        1050
+#   Scan Frequency      65.218 kHz  59.99 Hz
+#   Sync Width      1.037 us    0.047 ms
+#               19 chars    3 lines
+#   Front Porch     0.444 us    0.015 ms
+#               11 chars     1 lines
+#   Back Porch      1.185 us    0.188 ms
+#               30 chars    33 lines
+#   Active Time     12.963 us   16.411 ms
+#               175 chars   1050 lines
+#   Blank Time      2.667 us    0.250 ms
+#               60 chars    37 lines
+#   Polarity        negative    positive
+#
+    mode "1400x1050-60"
+# D: 122.750 MHz, H: 65.317 kHz, V: 59.99 Hz
+    geometry 1400 1050 1408 1050 32
+    timings 8214 232 88 32 3 144 4 endmode mode "1400x1050-75"
+# D: 156.000 MHz, H: 82.278 kHz, V: 74.867 Hz
+    geometry 1400 1050 1408 1050 32 timings 6410 248 104 42 3 144 4 endmode
+#
+#   1366x768, 60 Hz, Non-Interlaced (85.86 MHz dotclock)
+#
+#               Horizontal  Vertical
+#   Resolution      1366        768
+#   Scan Frequency      47.700 kHz  60.00 Hz
+#   Sync Width      1.677 us    0.063 ms
+#               18 chars    3 lines
+#   Front Porch     0.839 us    0.021 ms
+#               9 chars     1 lines
+#   Back Porch      2.516 us    0.482 ms
+#               27 chars    23 lines
+#   Active Time     15.933 us   16.101 ms
+#               171 chars   768 lines
+#   Blank Time      5.031 us    0.566 ms
+#               54 chars    27 lines
+#   Polarity        negative    positive
+#
+    mode "1360x768-60"
+# D: 84.750 MHz, H: 47.720 kHz, V: 60.00 Hz
+    geometry 1360 768 1360 768 32
+    timings 11799 208 72 22 3 136 5 endmode mode "1366x768-60"
+# D: 85.86 MHz, H: 47.700 kHz, V: 60.00 Hz
+    geometry 1366 768 1366 768 32
+    timings 11647 216 72 23 1 144 3 endmode mode "1366x768-50"
+# D: 69,924 MHz, H: 39.550 kHz, V: 50.00 Hz
+    geometry 1366 768 1366 768 32 timings 14301 200 56 19 1 144 3 endmode
diff --git a/Documentation/fb/viafb.txt b/Documentation/fb/viafb.txt
new file mode 100644 (file)
index 0000000..67dbf44
--- /dev/null
@@ -0,0 +1,214 @@
+
+        VIA Integration Graphic Chip Console Framebuffer Driver
+
+[Platform]
+-----------------------
+    The console framebuffer driver is for graphics chips of
+    VIA UniChrome Family(CLE266, PM800 / CN400 / CN300,
+                        P4M800CE / P4M800Pro / CN700 / VN800,
+                        CX700 / VX700, K8M890, P4M890,
+                        CN896 / P4M900, VX800)
+
+[Driver features]
+------------------------
+    Device: CRT, LCD, DVI
+
+    Support viafb_mode:
+        CRT:
+            640x480(60, 75, 85, 100, 120 Hz), 720x480(60 Hz),
+            720x576(60 Hz), 800x600(60, 75, 85, 100, 120 Hz),
+            848x480(60 Hz), 856x480(60 Hz), 1024x512(60 Hz),
+            1024x768(60, 75, 85, 100 Hz), 1152x864(75 Hz),
+            1280x768(60 Hz), 1280x960(60 Hz), 1280x1024(60, 75, 85 Hz),
+            1440x1050(60 Hz), 1600x1200(60, 75 Hz), 1280x720(60 Hz),
+            1920x1080(60 Hz), 1400x1050(60 Hz), 800x480(60 Hz)
+
+    color depth: 8 bpp, 16 bpp, 32 bpp supports.
+
+    Support 2D hardware accelerator.
+
+[Using the viafb module]
+-- -- --------------------
+    Start viafb with default settings:
+        #modprobe viafb
+
+    Start viafb with with user options:
+        #modprobe viafb viafb_mode=800x600 viafb_bpp=16 viafb_refresh=60
+                  viafb_active_dev=CRT+DVI viafb_dvi_port=DVP1
+                  viafb_mode1=1024x768 viafb_bpp=16 viafb_refresh1=60
+                  viafb_SAMM_ON=1
+
+    viafb_mode:
+        640x480 (default)
+        720x480
+        800x600
+        1024x768
+        ......
+
+    viafb_bpp:
+        8, 16, 32 (default:32)
+
+    viafb_refresh:
+        60, 75, 85, 100, 120 (default:60)
+
+    viafb_lcd_dsp_method:
+        0 : expansion (default)
+        1 : centering
+
+    viafb_lcd_mode:
+        0 : LCD panel with LSB data format input (default)
+        1 : LCD panel with MSB data format input
+
+    viafb_lcd_panel_id:
+        0 : Resolution: 640x480, Channel: single, Dithering: Enable
+        1 : Resolution: 800x600, Channel: single, Dithering: Enable
+        2 : Resolution: 1024x768, Channel: single, Dithering: Enable (default)
+        3 : Resolution: 1280x768, Channel: single, Dithering: Enable
+        4 : Resolution: 1280x1024, Channel: dual, Dithering: Enable
+        5 : Resolution: 1400x1050, Channel: dual, Dithering: Enable
+        6 : Resolution: 1600x1200, Channel: dual, Dithering: Enable
+
+        8 : Resolution: 800x480, Channel: single, Dithering: Enable
+        9 : Resolution: 1024x768, Channel: dual, Dithering: Enable
+        10: Resolution: 1024x768, Channel: single, Dithering: Disable
+        11: Resolution: 1024x768, Channel: dual, Dithering: Disable
+        12: Resolution: 1280x768, Channel: single, Dithering: Disable
+        13: Resolution: 1280x1024, Channel: dual, Dithering: Disable
+        14: Resolution: 1400x1050, Channel: dual, Dithering: Disable
+        15: Resolution: 1600x1200, Channel: dual, Dithering: Disable
+        16: Resolution: 1366x768, Channel: single, Dithering: Disable
+        17: Resolution: 1024x600, Channel: single, Dithering: Enable
+        18: Resolution: 1280x768, Channel: dual, Dithering: Enable
+        19: Resolution: 1280x800, Channel: single, Dithering: Enable
+
+    viafb_accel:
+        0 : No 2D Hardware Acceleration
+        1 : 2D Hardware Acceleration (default)
+
+    viafb_SAMM_ON:
+        0 : viafb_SAMM_ON disable (default)
+        1 : viafb_SAMM_ON enable
+
+    viafb_mode1: (secondary display device)
+        640x480 (default)
+        720x480
+        800x600
+        1024x768
+        ... ...
+
+    viafb_bpp1: (secondary display device)
+        8, 16, 32 (default:32)
+
+    viafb_refresh1: (secondary display device)
+        60, 75, 85, 100, 120 (default:60)
+
+    viafb_active_dev:
+        This option is used to specify active devices.(CRT, DVI, CRT+LCD...)
+        DVI stands for DVI or HDMI, E.g., If you want to enable HDMI,
+        set viafb_active_dev=DVI. In SAMM case, the previous of
+        viafb_active_dev is primary device, and the following is
+        secondary device.
+
+        For example:
+        To enable one device, such as DVI only, we can use:
+            modprobe viafb viafb_active_dev=DVI
+        To enable two devices, such as CRT+DVI:
+            modprobe viafb viafb_active_dev=CRT+DVI;
+
+        For DuoView case, we can use:
+            modprobe viafb viafb_active_dev=CRT+DVI
+            OR
+            modprobe viafb viafb_active_dev=DVI+CRT...
+
+        For SAMM case:
+        If CRT is primary and DVI is secondary, we should use:
+            modprobe viafb viafb_active_dev=CRT+DVI viafb_SAMM_ON=1...
+        If DVI is primary and CRT is secondary, we should use:
+            modprobe viafb viafb_active_dev=DVI+CRT viafb_SAMM_ON=1...
+
+    viafb_display_hardware_layout:
+        This option is used to specify display hardware layout for CX700 chip.
+        1 : LCD only
+        2 : DVI only
+        3 : LCD+DVI (default)
+        4 : LCD1+LCD2 (internal + internal)
+        16: LCD1+ExternalLCD2 (internal + external)
+
+    viafb_second_size:
+        This option is used to set second device memory size(MB) in SAMM case.
+        The minimal size is 16.
+
+    viafb_platform_epia_dvi:
+        This option is used to enable DVI on EPIA - M
+        0 : No DVI on EPIA - M (default)
+        1 : DVI on EPIA - M
+
+    viafb_bus_width:
+        When using 24 - Bit Bus Width Digital Interface,
+        this option should be set.
+        12: 12-Bit LVDS or 12-Bit TMDS (default)
+        24: 24-Bit LVDS or 24-Bit TMDS
+
+    viafb_device_lcd_dualedge:
+        When using Dual Edge Panel, this option should be set.
+        0 : No Dual Edge Panel (default)
+        1 : Dual Edge Panel
+
+    viafb_video_dev:
+        This option is used to specify video output devices(CRT, DVI, LCD) for
+        duoview case.
+        For example:
+        To output video on DVI, we should use:
+            modprobe viafb viafb_video_dev=DVI...
+
+    viafb_lcd_port:
+        This option is used to specify LCD output port,
+        available values are "DVP0" "DVP1" "DFP_HIGHLOW" "DFP_HIGH" "DFP_LOW".
+        for external LCD + external DVI on CX700(External LCD is on DVP0),
+        we should use:
+            modprobe viafb viafb_lcd_port=DVP0...
+
+Notes:
+    1. CRT may not display properly for DuoView CRT & DVI display at
+       the "640x480" PAL mode with DVI overscan enabled.
+    2. SAMM stands for single adapter multi monitors. It is different from
+       multi-head since SAMM support multi monitor at driver layers, thus fbcon
+       layer doesn't even know about it; SAMM's second screen doesn't have a
+       device node file, thus a user mode application can't access it directly.
+       When SAMM is enabled, viafb_mode and viafb_mode1, viafb_bpp and
+       viafb_bpp1, viafb_refresh and viafb_refresh1 can be different.
+    3. When console is depending on viafbinfo1, dynamically change resolution
+       and bpp, need to call VIAFB specified ioctl interface VIAFB_SET_DEVICE
+       instead of calling common ioctl function FBIOPUT_VSCREENINFO since
+       viafb doesn't support multi-head well, or it will cause screen crush.
+    4. VX800 2D accelerator hasn't been supported in this driver yet. When
+       using driver on VX800, the driver will disable the acceleration
+       function as default.
+
+
+[Configure viafb with "fbset" tool]
+-----------------------------------
+    "fbset" is an inbox utility of Linux.
+    1. Inquire current viafb information, type,
+           # fbset -i
+
+    2. Set various resolutions and viafb_refresh rates,
+           # fbset <resolution-vertical_sync>
+
+       example,
+           # fbset "1024x768-75"
+       or
+           # fbset -g 1024 768 1024 768 32
+       Check the file "/etc/fb.modes" to find display modes available.
+
+    3. Set the color depth,
+           # fbset -depth <value>
+
+       example,
+           # fbset -depth 16
+
+[Bootup with viafb]:
+--------------------
+    Add the following line to your grub.conf:
+    append = "video=viafb:viafb_mode=1024x768,viafb_bpp=32,viafb_refresh=85"
+
index 4d2566a7d16836d04f77c26bad5ebe6d38019dd9..f5f812daf9f439658bcc710164b2912dc2430e75 100644 (file)
@@ -294,6 +294,15 @@ Who:       Jiri Slaby <jirislaby@gmail.com>
 
 ---------------------------
 
+What: print_fn_descriptor_symbol()
+When: October 2009
+Why:  The %pF vsprintf format provides the same functionality in a
+      simpler way.  print_fn_descriptor_symbol() is deprecated but
+      still present to give out-of-tree modules time to change.
+Who:  Bjorn Helgaas <bjorn.helgaas@hp.com>
+
+---------------------------
+
 What:  /sys/o2cb symlink
 When:  January 2010
 Why:   /sys/fs/o2cb is the proper location for this information - /sys/o2cb
diff --git a/Documentation/filesystems/autofs4-mount-control.txt b/Documentation/filesystems/autofs4-mount-control.txt
new file mode 100644 (file)
index 0000000..c634174
--- /dev/null
@@ -0,0 +1,393 @@
+
+Miscellaneous Device control operations for the autofs4 kernel module
+====================================================================
+
+The problem
+===========
+
+There is a problem with active restarts in autofs (that is to say
+restarting autofs when there are busy mounts).
+
+During normal operation autofs uses a file descriptor opened on the
+directory that is being managed in order to be able to issue control
+operations. Using a file descriptor gives ioctl operations access to
+autofs specific information stored in the super block. The operations
+are things such as setting an autofs mount catatonic, setting the
+expire timeout and requesting expire checks. As is explained below,
+certain types of autofs triggered mounts can end up covering an autofs
+mount itself which prevents us being able to use open(2) to obtain a
+file descriptor for these operations if we don't already have one open.
+
+Currently autofs uses "umount -l" (lazy umount) to clear active mounts
+at restart. While using lazy umount works for most cases, anything that
+needs to walk back up the mount tree to construct a path, such as
+getcwd(2) and the proc file system /proc/<pid>/cwd, no longer works
+because the point from which the path is constructed has been detached
+from the mount tree.
+
+The actual problem with autofs is that it can't reconnect to existing
+mounts. Immediately one thinks of just adding the ability to remount
+autofs file systems would solve it, but alas, that can't work. This is
+because autofs direct mounts and the implementation of "on demand mount
+and expire" of nested mount trees have the file system mounted directly
+on top of the mount trigger directory dentry.
+
+For example, there are two types of automount maps, direct (in the kernel
+module source you will see a third type called an offset, which is just
+a direct mount in disguise) and indirect.
+
+Here is a master map with direct and indirect map entries:
+
+/-      /etc/auto.direct
+/test   /etc/auto.indirect
+
+and the corresponding map files:
+
+/etc/auto.direct:
+
+/automount/dparse/g6  budgie:/autofs/export1
+/automount/dparse/g1  shark:/autofs/export1
+and so on.
+
+/etc/auto.indirect:
+
+g1    shark:/autofs/export1
+g6    budgie:/autofs/export1
+and so on.
+
+For the above indirect map an autofs file system is mounted on /test and
+mounts are triggered for each sub-directory key by the inode lookup
+operation. So we see a mount of shark:/autofs/export1 on /test/g1, for
+example.
+
+The way that direct mounts are handled is by making an autofs mount on
+each full path, such as /automount/dparse/g1, and using it as a mount
+trigger. So when we walk on the path we mount shark:/autofs/export1 "on
+top of this mount point". Since these are always directories we can
+use the follow_link inode operation to trigger the mount.
+
+But, each entry in direct and indirect maps can have offsets (making
+them multi-mount map entries).
+
+For example, an indirect mount map entry could also be:
+
+g1  \
+   /        shark:/autofs/export5/testing/test \
+   /s1      shark:/autofs/export/testing/test/s1 \
+   /s2      shark:/autofs/export5/testing/test/s2 \
+   /s1/ss1  shark:/autofs/export1 \
+   /s2/ss2  shark:/autofs/export2
+
+and a similarly a direct mount map entry could also be:
+
+/automount/dparse/g1 \
+    /       shark:/autofs/export5/testing/test \
+    /s1     shark:/autofs/export/testing/test/s1 \
+    /s2     shark:/autofs/export5/testing/test/s2 \
+    /s1/ss1 shark:/autofs/export2 \
+    /s2/ss2 shark:/autofs/export2
+
+One of the issues with version 4 of autofs was that, when mounting an
+entry with a large number of offsets, possibly with nesting, we needed
+to mount and umount all of the offsets as a single unit. Not really a
+problem, except for people with a large number of offsets in map entries.
+This mechanism is used for the well known "hosts" map and we have seen
+cases (in 2.4) where the available number of mounts are exhausted or
+where the number of privileged ports available is exhausted.
+
+In version 5 we mount only as we go down the tree of offsets and
+similarly for expiring them which resolves the above problem. There is
+somewhat more detail to the implementation but it isn't needed for the
+sake of the problem explanation. The one important detail is that these
+offsets are implemented using the same mechanism as the direct mounts
+above and so the mount points can be covered by a mount.
+
+The current autofs implementation uses an ioctl file descriptor opened
+on the mount point for control operations. The references held by the
+descriptor are accounted for in checks made to determine if a mount is
+in use and is also used to access autofs file system information held
+in the mount super block. So the use of a file handle needs to be
+retained.
+
+
+The Solution
+============
+
+To be able to restart autofs leaving existing direct, indirect and
+offset mounts in place we need to be able to obtain a file handle
+for these potentially covered autofs mount points. Rather than just
+implement an isolated operation it was decided to re-implement the
+existing ioctl interface and add new operations to provide this
+functionality.
+
+In addition, to be able to reconstruct a mount tree that has busy mounts,
+the uid and gid of the last user that triggered the mount needs to be
+available because these can be used as macro substitution variables in
+autofs maps. They are recorded at mount request time and an operation
+has been added to retrieve them.
+
+Since we're re-implementing the control interface, a couple of other
+problems with the existing interface have been addressed. First, when
+a mount or expire operation completes a status is returned to the
+kernel by either a "send ready" or a "send fail" operation. The
+"send fail" operation of the ioctl interface could only ever send
+ENOENT so the re-implementation allows user space to send an actual
+status. Another expensive operation in user space, for those using
+very large maps, is discovering if a mount is present. Usually this
+involves scanning /proc/mounts and since it needs to be done quite
+often it can introduce significant overhead when there are many entries
+in the mount table. An operation to lookup the mount status of a mount
+point dentry (covered or not) has also been added.
+
+Current kernel development policy recommends avoiding the use of the
+ioctl mechanism in favor of systems such as Netlink. An implementation
+using this system was attempted to evaluate its suitability and it was
+found to be inadequate, in this case. The Generic Netlink system was
+used for this as raw Netlink would lead to a significant increase in
+complexity. There's no question that the Generic Netlink system is an
+elegant solution for common case ioctl functions but it's not a complete
+replacement probably because it's primary purpose in life is to be a
+message bus implementation rather than specifically an ioctl replacement.
+While it would be possible to work around this there is one concern
+that lead to the decision to not use it. This is that the autofs
+expire in the daemon has become far to complex because umount
+candidates are enumerated, almost for no other reason than to "count"
+the number of times to call the expire ioctl. This involves scanning
+the mount table which has proved to be a big overhead for users with
+large maps. The best way to improve this is try and get back to the
+way the expire was done long ago. That is, when an expire request is
+issued for a mount (file handle) we should continually call back to
+the daemon until we can't umount any more mounts, then return the
+appropriate status to the daemon. At the moment we just expire one
+mount at a time. A Generic Netlink implementation would exclude this
+possibility for future development due to the requirements of the
+message bus architecture.
+
+
+autofs4 Miscellaneous Device mount control interface
+====================================================
+
+The control interface is opening a device node, typically /dev/autofs.
+
+All the ioctls use a common structure to pass the needed parameter
+information and return operation results:
+
+struct autofs_dev_ioctl {
+       __u32 ver_major;
+       __u32 ver_minor;
+       __u32 size;             /* total size of data passed in
+                                * including this struct */
+       __s32 ioctlfd;          /* automount command fd */
+
+       __u32 arg1;             /* Command parameters */
+       __u32 arg2;
+
+       char path[0];
+};
+
+The ioctlfd field is a mount point file descriptor of an autofs mount
+point. It is returned by the open call and is used by all calls except
+the check for whether a given path is a mount point, where it may
+optionally be used to check a specific mount corresponding to a given
+mount point file descriptor, and when requesting the uid and gid of the
+last successful mount on a directory within the autofs file system.
+
+The fields arg1 and arg2 are used to communicate parameters and results of
+calls made as described below.
+
+The path field is used to pass a path where it is needed and the size field
+is used account for the increased structure length when translating the
+structure sent from user space.
+
+This structure can be initialized before setting specific fields by using
+the void function call init_autofs_dev_ioctl(struct autofs_dev_ioctl *).
+
+All of the ioctls perform a copy of this structure from user space to
+kernel space and return -EINVAL if the size parameter is smaller than
+the structure size itself, -ENOMEM if the kernel memory allocation fails
+or -EFAULT if the copy itself fails. Other checks include a version check
+of the compiled in user space version against the module version and a
+mismatch results in a -EINVAL return. If the size field is greater than
+the structure size then a path is assumed to be present and is checked to
+ensure it begins with a "/" and is NULL terminated, otherwise -EINVAL is
+returned. Following these checks, for all ioctl commands except
+AUTOFS_DEV_IOCTL_VERSION_CMD, AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and
+AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD the ioctlfd is validated and if it is
+not a valid descriptor or doesn't correspond to an autofs mount point
+an error of -EBADF, -ENOTTY or -EINVAL (not an autofs descriptor) is
+returned.
+
+
+The ioctls
+==========
+
+An example of an implementation which uses this interface can be seen
+in autofs version 5.0.4 and later in file lib/dev-ioctl-lib.c of the
+distribution tar available for download from kernel.org in directory
+/pub/linux/daemons/autofs/v5.
+
+The device node ioctl operations implemented by this interface are:
+
+
+AUTOFS_DEV_IOCTL_VERSION
+------------------------
+
+Get the major and minor version of the autofs4 device ioctl kernel module
+implementation. It requires an initialized struct autofs_dev_ioctl as an
+input parameter and sets the version information in the passed in structure.
+It returns 0 on success or the error -EINVAL if a version mismatch is
+detected.
+
+
+AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD
+------------------------------------------------------------------
+
+Get the major and minor version of the autofs4 protocol version understood
+by loaded module. This call requires an initialized struct autofs_dev_ioctl
+with the ioctlfd field set to a valid autofs mount point descriptor
+and sets the requested version number in structure field arg1. These
+commands return 0 on success or one of the negative error codes if
+validation fails.
+
+
+AUTOFS_DEV_IOCTL_OPENMOUNT and AUTOFS_DEV_IOCTL_CLOSEMOUNT
+----------------------------------------------------------
+
+Obtain and release a file descriptor for an autofs managed mount point
+path. The open call requires an initialized struct autofs_dev_ioctl with
+the the path field set and the size field adjusted appropriately as well
+as the arg1 field set to the device number of the autofs mount. The
+device number can be obtained from the mount options shown in
+/proc/mounts. The close call requires an initialized struct
+autofs_dev_ioct with the ioctlfd field set to the descriptor obtained
+from the open call. The release of the file descriptor can also be done
+with close(2) so any open descriptors will also be closed at process exit.
+The close call is included in the implemented operations largely for
+completeness and to provide for a consistent user space implementation.
+
+
+AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCTL_FAIL_CMD
+--------------------------------------------------------
+
+Return mount and expire result status from user space to the kernel.
+Both of these calls require an initialized struct autofs_dev_ioctl
+with the ioctlfd field set to the descriptor obtained from the open
+call and the arg1 field set to the wait queue token number, received
+by user space in the foregoing mount or expire request. The arg2 field
+is set to the status to be returned. For the ready call this is always
+0 and for the fail call it is set to the errno of the operation.
+
+
+AUTOFS_DEV_IOCTL_SETPIPEFD_CMD
+------------------------------
+
+Set the pipe file descriptor used for kernel communication to the daemon.
+Normally this is set at mount time using an option but when reconnecting
+to a existing mount we need to use this to tell the autofs mount about
+the new kernel pipe descriptor. In order to protect mounts against
+incorrectly setting the pipe descriptor we also require that the autofs
+mount be catatonic (see next call).
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call and
+the arg1 field set to descriptor of the pipe. On success the call
+also sets the process group id used to identify the controlling process
+(eg. the owning automount(8) daemon) to the process group of the caller.
+
+
+AUTOFS_DEV_IOCTL_CATATONIC_CMD
+------------------------------
+
+Make the autofs mount point catatonic. The autofs mount will no longer
+issue mount requests, the kernel communication pipe descriptor is released
+and any remaining waits in the queue released.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call.
+
+
+AUTOFS_DEV_IOCTL_TIMEOUT_CMD
+----------------------------
+
+Set the expire timeout for mounts withing an autofs mount point.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call.
+
+
+AUTOFS_DEV_IOCTL_REQUESTER_CMD
+------------------------------
+
+Return the uid and gid of the last process to successfully trigger a the
+mount on the given path dentry.
+
+The call requires an initialized struct autofs_dev_ioctl with the path
+field set to the mount point in question and the size field adjusted
+appropriately as well as the arg1 field set to the device number of the
+containing autofs mount. Upon return the struct field arg1 contains the
+uid and arg2 the gid.
+
+When reconstructing an autofs mount tree with active mounts we need to
+re-connect to mounts that may have used the original process uid and
+gid (or string variations of them) for mount lookups within the map entry.
+This call provides the ability to obtain this uid and gid so they may be
+used by user space for the mount map lookups.
+
+
+AUTOFS_DEV_IOCTL_EXPIRE_CMD
+---------------------------
+
+Issue an expire request to the kernel for an autofs mount. Typically
+this ioctl is called until no further expire candidates are found.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call. In
+addition an immediate expire, independent of the mount timeout, can be
+requested by setting the arg1 field to 1. If no expire candidates can
+be found the ioctl returns -1 with errno set to EAGAIN.
+
+This call causes the kernel module to check the mount corresponding
+to the given ioctlfd for mounts that can be expired, issues an expire
+request back to the daemon and waits for completion.
+
+AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD
+------------------------------
+
+Checks if an autofs mount point is in use.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call and
+it returns the result in the arg1 field, 1 for busy and 0 otherwise.
+
+
+AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD
+---------------------------------
+
+Check if the given path is a mountpoint.
+
+The call requires an initialized struct autofs_dev_ioctl. There are two
+possible variations. Both use the path field set to the path of the mount
+point to check and the size field adjusted appropriately. One uses the
+ioctlfd field to identify a specific mount point to check while the other
+variation uses the path and optionaly arg1 set to an autofs mount type.
+The call returns 1 if this is a mount point and sets arg1 to the device
+number of the mount and field arg2 to the relevant super block magic
+number (described below) or 0 if it isn't a mountpoint. In both cases
+the the device number (as returned by new_encode_dev()) is returned
+in field arg1.
+
+If supplied with a file descriptor we're looking for a specific mount,
+not necessarily at the top of the mounted stack. In this case the path
+the descriptor corresponds to is considered a mountpoint if it is itself
+a mountpoint or contains a mount, such as a multi-mount without a root
+mount. In this case we return 1 if the descriptor corresponds to a mount
+point and and also returns the super magic of the covering mount if there
+is one or 0 if it isn't a mountpoint.
+
+If a path is supplied (and the ioctlfd field is set to -1) then the path
+is looked up and is checked to see if it is the root of a mount. If a
+type is also given we are looking for a particular autofs mount and if
+a match isn't found a fail is returned. If the the located path is the
+root of a mount 1 is returned along with the super magic of the mount
+or 0 otherwise.
+
index b45f3c1b8b431655f500b0a8842553ea21a5d6a0..295f26cd895a0d5cd460267a84ebbb687978fa69 100644 (file)
@@ -193,6 +193,5 @@ kernel source:      <file:fs/ext3/>
 programs:      http://e2fsprogs.sourceforge.net/
                http://ext2resize.sourceforge.net
 
-useful links:  http://www.zip.com.au/~akpm/linux/ext3/ext3-usage.html
-               http://www-106.ibm.com/developerworks/linux/library/l-fs7/
+useful links:  http://www-106.ibm.com/developerworks/linux/library/l-fs7/
                http://www-106.ibm.com/developerworks/linux/library/l-fs8/
index 31b329172343546e8f1e1fb4a30549298d45ee68..68baddf3c3e04f0c75e03dcf58a83dc926d57644 100644 (file)
@@ -169,7 +169,7 @@ They depend on various facilities being available:
 3.1)  Booting from a floppy using syslinux
 
        When building kernels, an easy way to create a boot floppy that uses
-       syslinux is to use the zdisk or bzdisk make targets which use
+       syslinux is to use the zdisk or bzdisk make targets which use zimage
        and bzimage images respectively. Both targets accept the
        FDARGS parameter which can be used to set the kernel command line.
 
index b488edad743cef9c5d8fea84ab1dcb491aa38c87..c032bf39e8b9b581b6ada65f7a99b97b2dae7019 100644 (file)
@@ -1321,6 +1321,18 @@ debugging information is displayed on console.
 NMI switch that most IA32 servers have fires unknown NMI up, for example.
 If a system hangs up, try pressing the NMI switch.
 
+panic_on_unrecovered_nmi
+------------------------
+
+The default Linux behaviour on an NMI of either memory or unknown is to continue
+operation. For many environments such as scientific computing it is preferable
+that the box is taken out and the error dealt with than an uncorrected
+parity/ECC error get propogated.
+
+A small number of systems do generate NMI's for bizarre random reasons such as
+power management so the default is off. That sysctl works like the existing
+panic controls already in that directory.
+
 nmi_watchdog
 ------------
 
index 7be232b44ee4602f74dc0b75ed66d150c23a6aaf..62fe9b1e089031c2e30153e9dc1be6f15d30aa6c 100644 (file)
@@ -263,7 +263,7 @@ User Mode Linux, like so:
     sleep(999999999);
   }
   EOF
-  gcc -static hello2.c -o init
+  gcc -static hello.c -o init
   echo init | cpio -o -H newc | gzip > test.cpio.gz
   # Testing external initramfs using the initrd loading mechanism.
   qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero
index 18022e249c53dc1ad991d74d160551fa32f32070..b1b9887012478f9b654edaa90bcdd13e72a9f20e 100644 (file)
@@ -240,6 +240,10 @@ signal, or (b) something wrongly believes it's safe to remove drivers
 needed to manage a signal that's in active use.  That is, requesting a
 GPIO can serve as a kind of lock.
 
+Some platforms may also use knowledge about what GPIOs are active for
+power management, such as by powering down unused chip sectors and, more
+easily, gating off unused clocks.
+
 These two calls are optional because not not all current Linux platforms
 offer such functionality in their GPIO support; a valid implementation
 could return success for all gpio_request() calls.  Unlike the other calls,
@@ -264,7 +268,7 @@ map between them using calls like:
        /* map GPIO numbers to IRQ numbers */
        int gpio_to_irq(unsigned gpio);
 
-       /* map IRQ numbers to GPIO numbers */
+       /* map IRQ numbers to GPIO numbers (avoid using this) */
        int irq_to_gpio(unsigned irq);
 
 Those return either the corresponding number in the other namespace, or
@@ -284,7 +288,8 @@ system wakeup capabilities.
 
 Non-error values returned from irq_to_gpio() would most commonly be used
 with gpio_get_value(), for example to initialize or update driver state
-when the IRQ is edge-triggered.
+when the IRQ is edge-triggered.  Note that some platforms don't support
+this reverse mapping, so you should avoid using it.
 
 
 Emulating Open Drain Signals
index 914d07f49268b728ab5c1d8a6e7b23b59cef0128..84f7cb3d5bec43499965cb683d966f22ee15f85b 100644 (file)
@@ -1,7 +1,8 @@
-Currently, kvm module in EXPERIMENTAL stage on IA64. This means that
-interfaces are not stable enough to use. So, plase had better don't run
-critical applications in virtual machine. We will try our best to make it
-strong in future versions!
+Currently, kvm module is in EXPERIMENTAL stage on IA64. This means that
+interfaces are not stable enough to use. So, please don't run critical
+applications in virtual machine.
+We will try our best to improve it in future versions!
+
                                Guide: How to boot up guests on kvm/ia64
 
 This guide is to describe how to enable kvm support for IA-64 systems.
index 2443f5bb43648e5a2c50bc94d33703f88360880a..dd28a0d56981e4e0376fb5010086c817633a6a3b 100644 (file)
@@ -796,6 +796,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        Defaults to the default architecture's huge page size
                        if not specified.
 
+       i8042.debug     [HW] Toggle i8042 debug mode
        i8042.direct    [HW] Put keyboard port into non-translated mode
        i8042.dumbkbd   [HW] Pretend that controller can only read data from
                             keyboard and cannot control its state
@@ -1713,6 +1714,11 @@ and is between 256 and 4096 characters. It is defined in the file
                        autoconfiguration.
                        Ranges are in pairs (memory base and size).
 
+       dynamic_printk
+                       Enables pr_debug()/dev_dbg() calls if
+                       CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
+                       be switched on/off via <debugfs>/dynamic_printk/modules
+
        print-fatal-signals=
                        [KNL] debug: print fatal signals
                        print-fatal-signals=1: print segfault info to
index 51a8021ee532bc03e4e530dd724f3e42ae737bc4..f5d2aad65a672ce65082769b835d621bac11e59a 100644 (file)
@@ -118,6 +118,10 @@ the name of the kobject, call kobject_rename():
 
     int kobject_rename(struct kobject *kobj, const char *new_name);
 
+Note kobject_rename does perform any locking or have a solid notion of
+what names are valid so the provide must provide their own sanity checking
+and serialization.
+
 There is a function called kobject_set_name() but that is legacy cruft and
 is being removed.  If your code needs to call this function, it is
 incorrect and needs to be fixed.
index 6387d3decf858a7c83d2ae65f06c6eccdfa7dfae..c725d33b316fbadebb0d93d1fb70c193318ac1a2 100644 (file)
@@ -3,7 +3,7 @@ NOTE
 ----
 
 This document was contributed by Cirrus Logic for kernel 2.2.5.  This version
-has been updated for 2.3.48 by Andrew Morton <andrewm@uow.edu.au>
+has been updated for 2.3.48 by Andrew Morton.
 
 Cirrus make a copy of this driver available at their website, as
 described below.  In general, you should use the driver version which
@@ -690,7 +690,7 @@ latest drivers and technical publications.
 6.4 Current maintainer
 
 In February 2000 the maintenance of this driver was assumed by Andrew
-Morton <akpm@zip.com.au>
+Morton.
 
 6.5 Kernel module parameters
 
index 0e6e592f4f55b876c06b48ceae531b3cfdd6b421..6a07e45d4a9307aa208b88ae84cd97ab490fd0ac 100644 (file)
@@ -146,8 +146,8 @@ WARNING:
 When polling a connected pipe socket for writability, there is an
 intrinsic race condition whereby writability might be lost between the
 polling and the writing system calls. In this case, the socket will
-block until write because possible again, unless non-blocking mode
-becomes enabled.
+block until write becomes possible again, unless non-blocking mode
+is enabled.
 
 
 The pipe protocol provides two socket options at the SOL_PNPIPE level:
index 6356d3faed365634bbbe85172b28abdf472c600b..bd70976b816039e6e06c34e5f6924f0ee0130469 100644 (file)
@@ -1,5 +1,5 @@
 Documentation/networking/vortex.txt
-Andrew Morton <andrewm@uow.edu.au>
+Andrew Morton
 30 April 2000
 
 
@@ -11,7 +11,7 @@ The driver was written by Donald Becker <becker@scyld.com>
 Don is no longer the prime maintainer of this version of the driver. 
 Please report problems to one or more of:
 
-  Andrew Morton <akpm@osdl.org>
+  Andrew Morton
   Netdev mailing list <netdev@vger.kernel.org>
   Linux kernel mailing list <linux-kernel@vger.kernel.org>
 
@@ -305,11 +305,6 @@ Donald's wake-on-LAN page:
 
        ftp://ftp.3com.com/pub/nic/3c90x/3c90xx2.exe
 
-Driver updates and a detailed changelog for the modifications which
-were made for the 2.3/2,4 series kernel is available at
-
-     http://www.zip.com.au/~akpm/linux/#3c59x-bc
-
 
 Autonegotiation notes
 ---------------------
index b05f512130eaa1cb3f75da9414cf65d80cfe5b62..2ebdc6091ce17ff6464aeb4cec35939983045de6 100644 (file)
@@ -54,3 +54,21 @@ used to run with "radeonfb" (it's an ATI Radeon mobility). It turns out
 that "radeonfb" simply cannot resume that device - it tries to set the
 PLL's, and it just _hangs_. Using the regular VGA console and letting X
 resume it instead works fine.
+
+NOTE
+====
+pm_trace uses the system's Real Time Clock (RTC) to save the magic number.
+Reason for this is that the RTC is the only reliably available piece of
+hardware during resume operations where a value can be set that will
+survive a reboot.
+
+Consequence is that after a resume (even if it is successful) your system
+clock will have a value corresponding to the magic mumber instead of the
+correct date/time! It is therefore advisable to use a program like ntp-date
+or rdate to reset the correct date/time from an external time source when
+using this trace option.
+
+As the clock keeps ticking it is also essential that the reboot is done
+quickly after the resume failure. The trace option does not use the seconds
+or the low order bits of the minutes of the RTC, but a too long delay will
+corrupt the magic value.
index 29d839ce7327a01ad8ba24437b8840dcf9b70919..e3960b8c868940ebf6f39ec14e21735d023abf07 100644 (file)
@@ -18,10 +18,6 @@ mpc52xx.txt
        - Linux 2.6.x on MPC52xx family
 mpc52xx-device-tree-bindings.txt
        - MPC5200 Device Tree Bindings
-ppc_htab.txt
-       - info about the Linux/PPC /proc/ppc_htab entry
-smp.txt
-       - use and state info about Linux/PPC on MP machines
 sound.txt
        - info on sound support under Linux/PPC
 zImage_layout.txt
diff --git a/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt b/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt
new file mode 100644 (file)
index 0000000..35a4653
--- /dev/null
@@ -0,0 +1,40 @@
+* Freescale 83xx and 512x PCI bridges
+
+Freescale 83xx and 512x SOCs include the same pci bridge core.
+
+83xx/512x specific notes:
+- reg: should contain two address length tuples
+    The first is for the internal pci bridge registers
+    The second is for the pci config space access registers
+
+Example (MPC8313ERDB)
+       pci0: pci@e0008500 {
+               cell-index = <1>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                               /* IDSEL 0x0E -mini PCI */
+                                0x7000 0x0 0x0 0x1 &ipic 18 0x8
+                                0x7000 0x0 0x0 0x2 &ipic 18 0x8
+                                0x7000 0x0 0x0 0x3 &ipic 18 0x8
+                                0x7000 0x0 0x0 0x4 &ipic 18 0x8
+
+                               /* IDSEL 0x0F - PCI slot */
+                                0x7800 0x0 0x0 0x1 &ipic 17 0x8
+                                0x7800 0x0 0x0 0x2 &ipic 18 0x8
+                                0x7800 0x0 0x0 0x3 &ipic 17 0x8
+                                0x7800 0x0 0x0 0x4 &ipic 18 0x8>;
+               interrupt-parent = <&ipic>;
+               interrupts = <66 0x8>;
+               bus-range = <0x0 0x0>;
+               ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
+                         0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
+                         0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+               clock-frequency = <66666666>;
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
+               compatible = "fsl,mpc8349-pci";
+               device_type = "pci";
+       };
diff --git a/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt b/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt
new file mode 100644 (file)
index 0000000..d015dce
--- /dev/null
@@ -0,0 +1,40 @@
+GPIO controllers on MPC8xxx SoCs
+
+This is for the non-QE/CPM/GUTs GPIO controllers as found on
+8349, 8572, 8610 and compatible.
+
+Every GPIO controller node must have #gpio-cells property defined,
+this information will be used to translate gpio-specifiers.
+
+Required properties:
+- compatible : "fsl,<CHIP>-gpio" followed by "fsl,mpc8349-gpio" for
+  83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx.
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional parameters (currently unused).
+ - interrupts : Interrupt mapping for GPIO IRQ (currently unused).
+ - interrupt-parent : Phandle for the interrupt controller that
+   services interrupts for this device.
+- gpio-controller : Marks the port as GPIO controller.
+
+Example of gpio-controller nodes for a MPC8347 SoC:
+
+       gpio1: gpio-controller@c00 {
+               #gpio-cells = <2>;
+               compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
+               reg = <0xc00 0x100>;
+               interrupts = <74 0x8>;
+               interrupt-parent = <&ipic>;
+               gpio-controller;
+       };
+
+       gpio2: gpio-controller@d00 {
+               #gpio-cells = <2>;
+               compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
+               reg = <0xd00 0x100>;
+               interrupts = <75 0x8>;
+               interrupt-parent = <&ipic>;
+               gpio-controller;
+       };
+
+See booting-without-of.txt for details of how to specify GPIO
+information for devices.
index 86826df00e64ea66085c387d7fd68db46211963c..cc453110fc4651bcbc135e2dfc163e45776eb574 100644 (file)
@@ -20,7 +20,7 @@ Required properties:
         - compatible        : compatible list, contains 2 entries, first is
                         "fsl,CHIP-dma-channel", where CHIP is the processor
                         (mpc8349, mpc8350, etc.) and the second is
-                        "fsl,elo-dma-channel"
+                        "fsl,elo-dma-channel". However, see note below.
         - reg               : <registers mapping for channel>
         - cell-index        : dma channel index starts at 0.
 
@@ -82,7 +82,7 @@ Required properties:
         - compatible        : compatible list, contains 2 entries, first is
                         "fsl,CHIP-dma-channel", where CHIP is the processor
                         (mpc8540, mpc8560, etc.) and the second is
-                        "fsl,eloplus-dma-channel"
+                        "fsl,eloplus-dma-channel". However, see note below.
         - cell-index        : dma channel index starts at 0.
         - reg               : <registers mapping for channel>
         - interrupts        : <interrupt mapping for DMA channel IRQ>
@@ -125,3 +125,12 @@ Example:
                        interrupts = <17 2>;
                };
        };
+
+Note on DMA channel compatible properties: The compatible property must say
+"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA
+driver (fsldma).  Any DMA channel used by fsldma cannot be used by another
+DMA driver, such as the SSI sound drivers for the MPC8610.  Therefore, any DMA
+channel that should be used for another driver should not use
+"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel".  For the SSI drivers, for
+example, the compatible property should be "fsl,ssi-dma-channel".  See ssi.txt
+for more information.
index d100555d488a32e722cf4ae3f6640159018e9a83..a2d963998a654ab5042d67b24130dbf33dc12f71 100644 (file)
@@ -24,6 +24,12 @@ Required properties:
                    "rj-master" - r.j., SSI is clock master
                    "ac97-slave" - AC97 mode, SSI is clock slave
                    "ac97-master" - AC97 mode, SSI is clock master
+- fsl,playback-dma: phandle to a node for the DMA channel to use for
+                    playback of audio.  This is typically dictated by SOC
+                    design.  See the notes below.
+- fsl,capture-dma:  phandle to a node for the DMA channel to use for
+                    capture (recording) of audio.  This is typically dictated
+                    by SOC design.  See the notes below.
 
 Optional properties:
 - codec-handle   : phandle to a 'codec' node that defines an audio
@@ -36,3 +42,20 @@ Child 'codec' node required properties:
 Child 'codec' node optional properties:
 - clock-frequency  : The frequency of the input clock, which typically
                      comes from an on-board dedicated oscillator.
+
+Notes on fsl,playback-dma and fsl,capture-dma:
+
+On SOCs that have an SSI, specific DMA channels are hard-wired for playback
+and capture.  On the MPC8610, for example, SSI1 must use DMA channel 0 for
+playback and DMA channel 1 for capture.  SSI2 must use DMA channel 2 for
+playback and DMA channel 3 for capture.  The developer can choose which
+DMA controller to use, but the channels themselves are hard-wired.  The
+purpose of these two properties is to represent this hardware design.
+
+The device tree nodes for the DMA channels that are referenced by
+"fsl,playback-dma" and "fsl,capture-dma" must be marked as compatible with
+"fsl,ssi-dma-channel".  The SOC-specific compatible string (e.g.
+"fsl,mpc8610-dma-channel") can remain.  If these nodes are left as
+"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel", then the generic Elo DMA
+drivers (fsldma) will attempt to use them, and it will conflict with the
+sound drivers.
diff --git a/Documentation/powerpc/ppc_htab.txt b/Documentation/powerpc/ppc_htab.txt
deleted file mode 100644 (file)
index 8b8c7df..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-                 Information about /proc/ppc_htab
-=====================================================================
-
-This document and the related code was written by me (Cort Dougan), please
-email me (cort@fsmlabs.com) if you have questions, comments or corrections.
-
-Last Change: 2.16.98
-
-This entry in the proc directory is readable by all users but only
-writable by root.
-
-The ppc_htab interface is a user level way of accessing the
-performance monitoring registers as well as providing information
-about the PTE hash table.
-
-1. Reading
-
-  Reading this file will give you information about the memory management
-  hash table that serves as an extended tlb for page translation on the
-  powerpc.  It will also give you information about performance measurement
-  specific to the cpu that you are using.
-
-  Explanation of the 604 Performance Monitoring Fields:
-    MMCR0 - the current value of the MMCR0 register
-    PMC1
-    PMC2 - the value of the performance counters and a
-           description of what events they are counting
-           which are based on MMCR0 bit settings.
-  Explanation of the PTE Hash Table fields:
-
-    Size - hash table size in Kb.
-    Buckets -  number of buckets in the table.
-    Address - the virtual kernel address of the hash table base.
-    Entries - the number of ptes that can be stored in the hash table.
-    User/Kernel - how many pte's are in use by the kernel or user at that time.
-    Overflows - How many of the entries are in their secondary hash location.
-    Percent full - ratio of free pte entries to in use entries.
-    Reloads - Count of how many hash table misses have occurred
-              that were fixed with a reload from the linux tables.
-              Should always be 0 on 603 based machines.
-    Non-error Misses - Count of how many hash table misses have occurred
-              that were completed with the creation of a pte in the linux
-              tables with a call to do_page_fault().
-    Error Misses - Number of misses due to errors such as bad address
-              and permission violations.  This includes kernel access of
-              bad user addresses that are fixed up by the trap handler.
-
-  Note that calculation of the data displayed from /proc/ppc_htab takes
-  a long time and spends a great deal of time in the kernel.  It would
-  be quite hard on performance to read this file constantly.  In time
-  there may be a counter in the kernel that allows successive reads from
-  this file only after a given amount of time has passed to reduce the
-  possibility of a user slowing the system by reading this file.
-
-2. Writing
-
-  Writing to the ppc_htab allows you to change the characteristics of
-  the powerpc PTE hash table and setup performance monitoring.
-
-  Resizing the PTE hash table is not enabled right now due to many
-  complications with moving the hash table, rehashing the entries
-  and many many SMP issues that would have to be dealt with.
-
-  Write options to ppc_htab:
-  
-   - To set the size of the hash table to 64Kb:
-
-      echo 'size 64' > /proc/ppc_htab
-
-     The size must be a multiple of 64 and must be greater than or equal to
-     64.
-
-   - To turn off performance monitoring:
-
-      echo 'off' > /proc/ppc_htab
-
-   - To reset the counters without changing what they're counting:
-
-      echo 'reset' > /proc/ppc_htab
-
-     Note that counting will continue after the reset if it is enabled.
-
-   - To count only events in user mode or only in kernel mode:
-
-      echo 'user' > /proc/ppc_htab
-       ...or...
-      echo 'kernel' > /proc/ppc_htab
-
-     Note that these two options are exclusive of one another and the
-     lack of either of these options counts user and kernel.
-     Using 'reset' and 'off' reset these flags.
-
-   - The 604 has 2 performance counters which can each count events from
-     a specific set of events.  These sets are disjoint so it is not
-     possible to count _any_ combination of 2 events.  One event can
-     be counted by PMC1 and one by PMC2.
-
-     To start counting a particular event use:
-
-      echo 'event' > /proc/ppc_htab
-
-     and choose from these events:
-
-     PMC1
-     ----
-      'ic miss' - instruction cache misses
-      'dtlb' - data tlb misses (not hash table misses)
-
-     PMC2
-     ----
-      'dc miss' - data cache misses
-      'itlb' - instruction tlb misses (not hash table misses)
-      'load miss time' - cycles to complete a load miss
-
-3. Bugs
-
-  The PMC1 and PMC2 counters can overflow and give no indication of that
-  in /proc/ppc_htab.
diff --git a/Documentation/powerpc/smp.txt b/Documentation/powerpc/smp.txt
deleted file mode 100644 (file)
index 5b581b8..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-                 Information about Linux/PPC SMP mode
-=====================================================================
-
-This document and the related code was written by me
-(Cort Dougan, cort@fsmlabs.com) please email me if you have questions,
-comments or corrections.
-
-Last Change: 3.31.99
-
-If you want to help by writing code or testing different hardware please
-email me!
-
-1. State of Supported Hardware
-
-  PowerSurge Architecture - tested on UMAX s900, Apple 9600
-    The second processor on this machine boots up just fine and
-    enters its idle loop.  Hopefully a completely working SMP kernel
-    on this machine will be done shortly.
-
-    The code makes the assumption of only two processors.  The changes
-    necessary to work with any number would not be overly difficult but
-    I don't have any machines with >2 processors so it's not high on my
-    list of priorities.  If anyone else would like do to the work email
-    me and I can point out the places that need changed.  If you have >2
-    processors and don't want to add support yourself let me know and I
-    can take a look into it.
-
-  BeBox
-    BeBox support hasn't been added to the 2.1.X kernels from 2.0.X
-    but work is being done and SMP support for BeBox is in the works.
-
-  CHRP
-    CHRP SMP works and is fairly solid.  It's been tested on the IBM F50
-    with 4 processors for quite some time now.
index 37796fe45bd00a0a31fa9bc4a3a6a12decbe1606..eaa4801f2ce6aecfb0f7c1b3ca5f91ceb58341fd 100644 (file)
@@ -409,7 +409,7 @@ i.  Function reordering so that inline functions are defined before they
        megaraid_mbox_prepare_pthru, megaraid_mbox_prepare_epthru,
        megaraid_busywait_mbox
 
-               - Andrew Morton <akpm@osdl.org>, 08.19.2004
+               - Andrew Morton, 08.19.2004
                linux-scsi mailing list
 
        "Something else to clean up after inclusion: every instance of an
@@ -471,13 +471,13 @@ vi.       Add support for 64-bit applications. Current drivers assume only
 vii.   Move the function declarations for the management module from
        megaraid_mm.h to megaraid_mm.c
 
-               - Andrew Morton <akpm@osdl.org>, 08.19.2004
+               - Andrew Morton, 08.19.2004
                linux-scsi mailing list
 
 viii.  Change default values for MEGARAID_NEWGEN, MEGARAID_MM, and
        MEGARAID_MAILBOX to 'n' in Kconfig.megaraid
 
-               - Andrew Morton <akpm@osdl.org>, 08.19.2004
+               - Andrew Morton, 08.19.2004
                linux-scsi mailing list
 
 ix.    replace udelay with msleep
index bbe8dee681a5d2b9a503d7f59b22e79d7a3e9014..6bb916d57c957754fd9b4915c4d1a42e3a4cc8ac 100644 (file)
@@ -96,7 +96,7 @@ Each slave device attached to the PXA must provide slave specific configuration
 information via the structure "pxa2xx_spi_chip" found in
 "arch/arm/mach-pxa/include/mach/pxa2xx_spi.h".  The pxa2xx_spi master controller driver
 will uses the configuration whenever the driver communicates with the slave
-device.
+device. All fields are optional.
 
 struct pxa2xx_spi_chip {
        u8 tx_threshold;
@@ -112,14 +112,17 @@ used to configure the SSP hardware fifo.  These fields are critical to the
 performance of pxa2xx_spi driver and misconfiguration will result in rx
 fifo overruns (especially in PIO mode transfers). Good default values are
 
-       .tx_threshold = 12,
-       .rx_threshold = 4,
+       .tx_threshold = 8,
+       .rx_threshold = 8,
+
+The range is 1 to 16 where zero indicates "use default".
 
 The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA
 engine and is related the "spi_device.bits_per_word" field.  Read and understand
 the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers
 to determine the correct value. An SSP configured for byte-wide transfers would
-use a value of 8.
+use a value of 8. The driver will determine a reasonable default if
+dma_burst_size == 0.
 
 The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle
 trailing bytes in the SSP receiver fifo.  The correct value for this field is
@@ -137,7 +140,13 @@ function for asserting/deasserting a slave device chip select.  If the field is
 NULL, the pxa2xx_spi master controller driver assumes that the SSP port is
 configured to use SSPFRM instead.
 
-NSSP SALVE SAMPLE
+NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the
+chipselect is dropped after each spi_transfer.  Most devices need chip select
+asserted around the complete message.  Use SSPFRM as a GPIO (through cs_control)
+to accomodate these chips.
+
+
+NSSP SLAVE SAMPLE
 -----------------
 The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the
 "spi_board_info.controller_data" field. Below is a sample configuration using
@@ -206,18 +215,21 @@ static void __init streetracer_init(void)
 
 DMA and PIO I/O Support
 -----------------------
-The pxa2xx_spi driver support both DMA and interrupt driven PIO message
-transfers.  The driver defaults to PIO mode and DMA transfers must enabled by
-setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and
-ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero.  The DMA
-mode support both coherent and stream based DMA mappings.
+The pxa2xx_spi driver supports both DMA and interrupt driven PIO message
+transfers.  The driver defaults to PIO mode and DMA transfers must be enabled
+by setting the "enable_dma" flag in the "pxa2xx_spi_master" structure.  The DMA
+mode supports both coherent and stream based DMA mappings.
 
 The following logic is used to determine the type of I/O to be used on
 a per "spi_transfer" basis:
 
-if !enable_dma or dma_burst_size == 0 then
+if !enable_dma then
        always use PIO transfers
 
+if spi_message.len > 8191 then
+       print "rate limited" warning
+       use PIO transfers
+
 if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then
        use coherent DMA mode
 
index 5270cf4cb109f93a1505e4185f318a60f1fcd252..cb49802745dcb1c7838223b77d59c11e8e108b6b 100644 (file)
@@ -1,5 +1,7 @@
 00-INDEX
        - This file
+slaves/
+       - Drivers that provide support for specific family codes.
 masters/
        - Individual chips providing 1-wire busses.
 w1.generic
index 239f9ae018432c0ad23a33603bf429e062a40866..28176def3d6f3430c0b2c71c6be9d6b180914cf9 100644 (file)
@@ -16,3 +16,55 @@ which allows to build USB <-> W1 bridges.
 DS9490(R) is a USB <-> W1 bus master device
 which has 0x81 family ID integrated chip and DS2490
 low-level operational chip.
+
+Notes and limitations.
+- The weak pullup current is a minimum of 0.9mA and maximum of 6.0mA.
+- The 5V strong pullup is supported with a minimum of 5.9mA and a
+  maximum of 30.4 mA.  (From DS2490.pdf)
+- While the ds2490 supports a hardware search the code doesn't take
+  advantage of it (in tested case it only returned first device).
+- The hardware will detect when devices are attached to the bus on the
+  next bus (reset?) operation, however only a message is printed as
+  the core w1 code doesn't make use of the information.  Connecting
+  one device tends to give multiple new device notifications.
+- The number of USB bus transactions could be reduced if w1_reset_send
+  was added to the API.  The name is just a suggestion.  It would take
+  a write buffer and a read buffer (along with sizes) as arguments.
+  The ds2490 block I/O command supports reset, write buffer, read
+  buffer, and strong pullup all in one command, instead of the current
+  1 reset bus, 2 write the match rom command and slave rom id, 3 block
+  write and read data.  The write buffer needs to have the match rom
+  command and slave rom id prepended to the front of the requested
+  write buffer, both of which are known to the driver.
+- The hardware supports normal, flexible, and overdrive bus
+  communication speeds, but only the normal is supported.
+- The registered w1_bus_master functions don't define error
+  conditions.  If a bus search is in progress and the ds2490 is
+  removed it can produce a good amount of error output before the bus
+  search finishes.
+- The hardware supports detecting some error conditions, such as
+  short, alarming presence on reset, and no presence on reset, but the
+  driver doesn't query those values.
+- The ds2490 specification doesn't cover short bulk in reads in
+  detail, but my observation is if fewer bytes are requested than are
+  available, the bulk read will return an error and the hardware will
+  clear the entire bulk in buffer.  It would be possible to read the
+  maximum buffer size to not run into this error condition, only extra
+  bytes in the buffer is a logic error in the driver.  The code should
+  should match reads and writes as well as data sizes.  Reads and
+  writes are serialized and the status verifies that the chip is idle
+  (and data is available) before the read is executed, so it should
+  not happen.
+- Running x86_64 2.6.24 UHCI under qemu 0.9.0 under x86_64 2.6.22-rc6
+  with a OHCI controller, ds2490 running in the guest would operate
+  normally the first time the module was loaded after qemu attached
+  the ds2490 hardware, but if the module was unloaded, then reloaded
+  most of the time one of the bulk out or in, and usually the bulk in
+  would fail.  qemu sets a 50ms timeout and the bulk in would timeout
+  even when the status shows data available.  A bulk out write would
+  show a successful completion, but the ds2490 status register would
+  show 0 bytes written.  Detaching qemu from the ds2490 hardware and
+  reattaching would clear the problem.  usbmon output in the guest and
+  host did not explain the problem.  My guess is a bug in either qemu
+  or the host OS and more likely the host OS.
+-- 03-06-2008 David Fries <David@Fries.net>
diff --git a/Documentation/w1/slaves/00-INDEX b/Documentation/w1/slaves/00-INDEX
new file mode 100644 (file)
index 0000000..f8101d6
--- /dev/null
@@ -0,0 +1,4 @@
+00-INDEX
+       - This file
+w1_therm
+       - The Maxim/Dallas Semiconductor ds18*20 temperature sensor.
diff --git a/Documentation/w1/slaves/w1_therm b/Documentation/w1/slaves/w1_therm
new file mode 100644 (file)
index 0000000..0403aaa
--- /dev/null
@@ -0,0 +1,41 @@
+Kernel driver w1_therm
+====================
+
+Supported chips:
+  * Maxim ds18*20 based temperature sensors.
+
+Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+
+
+Description
+-----------
+
+w1_therm provides basic temperature conversion for ds18*20 devices.
+supported family codes:
+W1_THERM_DS18S20       0x10
+W1_THERM_DS1822                0x22
+W1_THERM_DS18B20       0x28
+
+Support is provided through the sysfs w1_slave file.  Each open and
+read sequence will initiate a temperature conversion then provide two
+lines of ASCII output.  The first line contains the nine hex bytes
+read along with a calculated crc value and YES or NO if it matched.
+If the crc matched the returned values are retained.  The second line
+displays the retained values along with a temperature in millidegrees
+Centigrade after t=.
+
+Parasite powered devices are limited to one slave performing a
+temperature conversion at a time.  If none of the devices are parasite
+powered it would be possible to convert all the devices at the same
+time and then go back to read individual sensors.  That isn't
+currently supported.  The driver also doesn't support reduced
+precision (which would also reduce the conversion time).
+
+The module parameter strong_pullup can be set to 0 to disable the
+strong pullup or 1 to enable.  If enabled the 5V strong pullup will be
+enabled when the conversion is taking place provided the master driver
+must support the strong pullup (or it falls back to a pullup
+resistor).  The DS18b20 temperature sensor specification lists a
+maximum current draw of 1.5mA and that a 5k pullup resistor is not
+sufficient.  The strong pullup is designed to provide the additional
+current required.
index 4c6509dd478923285bc883867635fe8365faa77b..e3333eec4320c2a4d679a111a19539523781f428 100644 (file)
@@ -79,10 +79,13 @@ w1 master sysfs interface
 <xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial
 bus                - (standard) symlink to the w1 bus
 driver             - (standard) symlink to the w1 driver
+w1_master_add      - Manually register a slave device
 w1_master_attempts - the number of times a search was attempted
 w1_master_max_slave_count
                    - the maximum slaves that may be attached to a master
 w1_master_name     - the name of the device (w1_bus_masterX)
+w1_master_pullup   - 5V strong pullup 0 enabled, 1 disabled
+w1_master_remove   - Manually remove a slave device
 w1_master_search   - the number of searches left to do, -1=continual (default)
 w1_master_slave_count
                    - the number of slaves found
@@ -90,7 +93,13 @@ w1_master_slaves   - the names of the slaves, one per line
 w1_master_timeout  - the delay in seconds between searches
 
 If you have a w1 bus that never changes (you don't add or remove devices),
-you can set w1_master_search to a positive value to disable searches.
+you can set the module parameter search_count to a small positive number
+for an initially small number of bus searches.  Alternatively it could be
+set to zero, then manually add the slave device serial numbers by
+w1_master_add device file.  The w1_master_add and w1_master_remove files
+generally only make sense when searching is disabled, as a search will
+redetect manually removed devices that are present and timeout manually
+added devices that aren't on the bus.
 
 
 w1 slave sysfs interface
index 5d0b8a23d63968e8d1c57640024fb2951cb1efcc..57975bda92014b4d83ad5a0fc783f09bb3f6ad05 100644 (file)
@@ -1629,6 +1629,11 @@ P:       Christopher Hoover
 M:     ch@murgatroid.com, ch@hpl.hp.com
 S:     Maintained
 
+EPSON S1D13XXX FRAMEBUFFER DRIVER
+P:     Kristoffer Ericson
+M:     kristoffer.ericson@gmail.com
+S:     Maintained
+
 ETHEREXPRESS-16 NETWORK DRIVER
 P:     Philip Blundell
 M:     philb@gnu.org
@@ -4089,7 +4094,7 @@ W:        http://tpmdd.sourceforge.net
 P:     Marcel Selhorst
 M:     tpm@selhorst.net
 W:     http://www.prosec.rub.de/tpm/
-L:     tpmdd-devel@lists.sourceforge.net
+L:     tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
 S:     Maintained
 
 TRIVIAL PATCHES
@@ -4480,6 +4485,13 @@ W:       http://kernel.org/~kzak/util-linux-ng/
 T:     git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
 S:     Maintained
 
+UVESAFB DRIVER
+P:     Michal Januszewski
+M:     spock@gentoo.org
+L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+W:     http://dev.gentoo.org/~spock/projects/uvesafb/
+S:     Maintained
+
 VFAT/FAT/MSDOS FILESYSTEM
 P:     OGAWA Hirofumi
 M:     hirofumi@mail.parknet.co.jp
@@ -4497,6 +4509,14 @@ M:       khali@linux-fr.org
 L:     i2c@lm-sensors.org
 S:     Maintained
 
+VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
+P:     Joseph Chan
+M:     JosephChan@via.com.tw
+P:     Scott Fang
+M:     ScottFang@viatech.com.cn
+L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+S:     Maintained
+
 VIA VELOCITY NETWORK DRIVER
 P:     Francois Romieu
 M:     romieu@fr.zoreil.com
@@ -4598,7 +4618,7 @@ WM97XX TOUCHSCREEN DRIVERS
 P:     Mark Brown
 M:     broonie@opensource.wolfsonmicro.com
 P:     Liam Girdwood
-M:     liam.girdwood@wolfsonmicro.com
+M:     lrg@slimlogic.co.uk
 L:     linux-input@vger.kernel.org
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-touch
 W:     http://opensource.wolfsonmicro.com/node/7
index 0267babe5eb9dc6a6c79f2347234b7d78aafc2e8..e6ab550bceb3fda92cf1ad1e67d1e3cee1af9005 100644 (file)
@@ -28,7 +28,7 @@ config OPROFILE_IBS
          If unsure, say N.
 
 config HAVE_OPROFILE
-       def_bool n
+       bool
 
 config KPROBES
        bool "Kprobes"
@@ -42,7 +42,7 @@ config KPROBES
          If in doubt, say "N".
 
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
-       def_bool n
+       bool
        help
          Some architectures are unable to perform unaligned accesses
          without the use of get_unaligned/put_unaligned. Others are
@@ -65,13 +65,13 @@ config KRETPROBES
        depends on KPROBES && HAVE_KRETPROBES
 
 config HAVE_IOREMAP_PROT
-       def_bool n
+       bool
 
 config HAVE_KPROBES
-       def_bool n
+       bool
 
 config HAVE_KRETPROBES
-       def_bool n
+       bool
 
 #
 # An arch should select this if it provides all these things:
@@ -89,16 +89,16 @@ config HAVE_KRETPROBES
 #      signal delivery         calls tracehook_signal_handler()
 #
 config HAVE_ARCH_TRACEHOOK
-       def_bool n
+       bool
 
 config HAVE_DMA_ATTRS
-       def_bool n
+       bool
 
 config USE_GENERIC_SMP_HELPERS
-       def_bool n
+       bool
 
 config HAVE_CLK
-       def_bool n
+       bool
        help
          The <linux/clk.h> calls support software clock gating and
          thus are a key power management tool on many systems.
index ee35226c44e94ff7fcedb0157016af8c4d08f781..a0f642b6a4b92b556e08c8c1d1e357979cd48322 100644 (file)
@@ -222,8 +222,7 @@ config ALPHA_MIATA
        bool "Miata"
        help
          The Digital PersonalWorkStation (PWS 433a, 433au, 500a, 500au, 600a,
-         or 600au).  There is an Installation HOWTO for this hardware at
-         <http://eijk.homelinux.org/~stefan/miata.html>.
+         or 600au).
 
 config ALPHA_MIKASA
        bool "Mikasa"
index 02ce8473870a96c326b91fe8a8f321b0c734dc0f..acdc681231cb49c2c11b8e47564bf02542bd3742 100644 (file)
@@ -95,7 +95,7 @@ struct exec
    Worse, we have to notice the start address before swapping to use
    /sbin/loader, which of course is _not_ a TASO application.  */
 #define SET_AOUT_PERSONALITY(BFPM, EX) \
-       set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
+       set_personality (((BFPM->taso || EX.ah.entry < 0x100000000L \
                           ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
 
 #endif /* __KERNEL__ */
index fc1002ea1e0c766c5150e633d1a83dfa7700a17f..5c75c1b2352a9cacf7c47de5c04d57b1bab7211b 100644 (file)
@@ -144,9 +144,9 @@ extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
        : amask (AMASK_CIX) ? "ev6" : "ev67");  \
 })
 
-#define SET_PERSONALITY(EX, IBCS2)                             \
+#define SET_PERSONALITY(EX)                                    \
        set_personality(((EX).e_flags & EF_ALPHA_32BIT)         \
-          ? PER_LINUX_32BIT : (IBCS2) ? PER_SVR4 : PER_LINUX)
+          ? PER_LINUX_32BIT : PER_LINUX)
 
 extern int alpha_l1i_cacheshape;
 extern int alpha_l1d_cacheshape;
index 2179c602032a6e5a7a4d55ec59bca02e2a745334..b9094da05d7a136a5dff6bf7a6a0751e25af5316 100644 (file)
@@ -41,13 +41,6 @@ mk_iommu_pte(unsigned long paddr)
        return (paddr >> (PAGE_SHIFT-1)) | 1;
 }
 
-static inline long
-calc_npages(long bytes)
-{
-       return (bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
-}
-\f
-
 /* Return the minimum of MAX or the first power of two larger
    than main memory.  */
 
@@ -287,7 +280,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
        if (!arena || arena->dma_base + arena->size - 1 > max_dma)
                arena = hose->sg_isa;
 
-       npages = calc_npages((paddr & ~PAGE_MASK) + size);
+       npages = iommu_num_pages(paddr, size, PAGE_SIZE);
 
        /* Force allocation to 64KB boundary for ISA bridges. */
        if (pdev && pdev == isa_bridge)
@@ -387,7 +380,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
                BUG();
        }
 
-       npages = calc_npages((dma_addr & ~PAGE_MASK) + size);
+       npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
 
        spin_lock_irqsave(&arena->lock, flags);
 
@@ -580,7 +573,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
           contiguous.  */
 
        paddr &= ~PAGE_MASK;
-       npages = calc_npages(paddr + size);
+       npages = iommu_num_pages(paddr, size, PAGE_SIZE);
        dma_ofs = iommu_arena_alloc(dev, arena, npages, 0);
        if (dma_ofs < 0) {
                /* If we attempted a direct map above but failed, die.  */
@@ -616,7 +609,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
                        sg++;
                }
 
-               npages = calc_npages((paddr & ~PAGE_MASK) + size);
+               npages = iommu_num_pages(paddr, size, PAGE_SIZE);
 
                paddr &= PAGE_MASK;
                for (i = 0; i < npages; ++i, paddr += PAGE_SIZE)
@@ -775,7 +768,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
                DBGA("    (%ld) sg [%lx,%lx]\n",
                     sg - end + nents, addr, size);
 
-               npages = calc_npages((addr & ~PAGE_MASK) + size);
+               npages = iommu_num_pages(addr, size, PAGE_SIZE);
                ofs = (addr - arena->dma_base) >> PAGE_SHIFT;
                iommu_arena_free(arena, ofs, npages);
 
index 06b6fdab639f879d56529611381f94627ee5e52f..e657c45d91d27c5a62f7d542ab9d36f3adcb9109 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/cache.h>
 #include <linux/profile.h>
 #include <linux/bitops.h>
+#include <linux/cpu.h>
 
 #include <asm/hwrpb.h>
 #include <asm/ptrace.h>
index e2274bc0b5441d249c225a0a49eb5474b490e14e..7d5121260fda0370fe85303120544af07689cf79 100644 (file)
@@ -118,9 +118,10 @@ endif
  machine-$(CONFIG_ARCH_IXP23XX)    := ixp23xx
  machine-$(CONFIG_ARCH_OMAP1)     := omap1
  machine-$(CONFIG_ARCH_OMAP2)     := omap2
+ machine-$(CONFIG_ARCH_OMAP3)     := omap2
     plat-$(CONFIG_ARCH_OMAP)      := omap
  machine-$(CONFIG_ARCH_S3C2410)           := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
-    plat-$(CONFIG_PLAT_S3C24XX)           := s3c24xx
+    plat-$(CONFIG_PLAT_S3C24XX)           := s3c24xx s3c
  machine-$(CONFIG_ARCH_LH7A40X)           := lh7a40x
  machine-$(CONFIG_ARCH_VERSATILE)  := versatile
  machine-$(CONFIG_ARCH_IMX)       := imx
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
new file mode 100644 (file)
index 0000000..e042d27
--- /dev/null
@@ -0,0 +1,1321 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc8
+# Wed Oct  1 17:14:22 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_MUX is not set
+# CONFIG_OMAP_MCBSP is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+CONFIG_MACH_OMAP3_BEAGLE=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_M66592=y
+CONFIG_USB_M66592=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig
new file mode 100644 (file)
index 0000000..948a212
--- /dev/null
@@ -0,0 +1,1044 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc5
+# Fri Oct 10 11:49:41 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_OMAP_SERIAL_WAKE=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_OMAP_LDP=y
+# CONFIG_MACH_OVERO is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+CONFIG_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/overo_defconfig b/arch/arm/configs/overo_defconfig
new file mode 100644 (file)
index 0000000..4920096
--- /dev/null
@@ -0,0 +1,1885 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc8
+# Fri Oct  3 11:50:34 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_OVERO=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=" debug "
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+CONFIG_CFG80211=y
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_93CX6=m
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_DELAY=m
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_USB=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_LIBERTAS_DEBUG=y
+CONFIG_USB_ZD1201=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_RTL8187=m
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_P54_COMMON=m
+CONFIG_P54_USB=m
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+CONFIG_SENSORS_EEPROM=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX2341X=m
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_AU0828 is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+# CONFIG_USB_GSPCA is not set
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+# CONFIG_VIDEO_EM28XX is not set
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+# CONFIG_USB_ET61X251 is not set
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_ZR364XX=m
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+# CONFIG_DVB_USB_DW2102 is not set
+# CONFIG_DVB_USB_ANYSEE is not set
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+# CONFIG_DVB_CINERGYT2_TUNING is not set
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+# CONFIG_DVB_DRX397XD is not set
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_S5H1409=m
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_S5H1411=m
+
+#
+# Digital terrestrial only tuners/PLL
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6405 is not set
+CONFIG_DVB_ISL6421=m
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_VERBOSE is not set
+# CONFIG_SND_PCM_XRUN_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_RIO500 is not set
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 5be016980c193ddef8b7cdcb5ffa0be32d55d1fe..a58378c343b9d3143f5e0116808b2bd1f690ba41 100644 (file)
@@ -107,6 +107,6 @@ extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
 #define ELF_PLAT_INIT(_r, load_addr)   (_r)->ARM_r0 = 0
 
 extern void elf_set_personality(const struct elf32_hdr *);
-#define SET_PERSONALITY(ex, ibcs2)     elf_set_personality(&(ex))
+#define SET_PERSONALITY(ex)    elf_set_personality(&(ex))
 
 #endif
index e4f72d202cc04acc6b9e3e60261457052434871f..44d4c2e8207b1b06a368fbe30b99ecc75f726302 100644 (file)
@@ -184,7 +184,6 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
 {
 
        /* set default policy and cpuinfo */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        policy->cpuinfo.max_freq = 160000;
        policy->cpuinfo.min_freq = 12000;
        policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */
index 478c2c9a22cb02cfda5bb3472f6b911f0790483b..5fba207317100f4ed3cacb9361e134a4e75ee926 100644 (file)
@@ -201,7 +201,7 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
                return -EINVAL;
 
        parent = clk->parent;
-       if (unlikely(parent == 0))
+       if (unlikely(parent == NULL))
                return -EIO;
 
        realrate = parent->rate;
@@ -499,7 +499,7 @@ static int omap1_clk_enable_generic(struct clk *clk)
        if (clk->flags & ALWAYS_ENABLED)
                return 0;
 
-       if (unlikely(clk->enable_reg == 0)) {
+       if (unlikely(clk->enable_reg == NULL)) {
                printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
                       clk->name);
                return -EINVAL;
@@ -535,7 +535,7 @@ static void omap1_clk_disable_generic(struct clk *clk)
        __u16 regval16;
        __u32 regval32;
 
-       if (clk->enable_reg == 0)
+       if (clk->enable_reg == NULL)
                return;
 
        if (clk->flags & ENABLE_REG_32BIT) {
@@ -577,7 +577,7 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
                return clk->parent->rate / (1 << dsor_exp);
        }
 
-       if(clk->round_rate != 0)
+       if (clk->round_rate != NULL)
                return clk->round_rate(clk, rate);
 
        return clk->rate;
@@ -625,7 +625,7 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
 
        /* Clocks in the DSP domain need api_ck. Just assume bootloader
         * has not enabled any DSP clocks */
-       if ((u32)clk->enable_reg == DSP_IDLECT2) {
+       if (clk->enable_reg == DSP_IDLECT2) {
                printk(KERN_INFO "Skipping reset check for DSP domain "
                       "clock \"%s\"\n", clk->name);
                return;
index 6eadf72828d8900ebbfbff69894b380cc5b80114..5635b511ab6f0b5d1546fef5dec6ed52d70e3c96 100644 (file)
@@ -324,7 +324,7 @@ static struct clk dspper_ck = {
        .parent         = &ck_dpll1,
        .flags          = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
                          RATE_CKCTL | VIRTUAL_IO_ADDRESS,
-       .enable_reg     = (void __iomem *)DSP_IDLECT2,
+       .enable_reg     = DSP_IDLECT2,
        .enable_bit     = EN_PERCK,
        .rate_offset    = CKCTL_PERDIV_OFFSET,
        .recalc         = &omap1_ckctl_recalc_dsp_domain,
@@ -338,7 +338,7 @@ static struct clk dspxor_ck = {
        .parent         = &ck_ref,
        .flags          = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
                          VIRTUAL_IO_ADDRESS,
-       .enable_reg     = (void __iomem *)DSP_IDLECT2,
+       .enable_reg     = DSP_IDLECT2,
        .enable_bit     = EN_XORPCK,
        .recalc         = &followparent_recalc,
        .enable         = &omap1_clk_enable_dsp_domain,
@@ -350,7 +350,7 @@ static struct clk dsptim_ck = {
        .parent         = &ck_ref,
        .flags          = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
                          VIRTUAL_IO_ADDRESS,
-       .enable_reg     = (void __iomem *)DSP_IDLECT2,
+       .enable_reg     = DSP_IDLECT2,
        .enable_bit     = EN_DSPTIMCK,
        .recalc         = &followparent_recalc,
        .enable         = &omap1_clk_enable_dsp_domain,
index 99982d3380c96d27f522a7b970d463e6cc53f454..e382b438c64ed5d42d49f05e1586ab03c3218aa5 100644 (file)
@@ -101,7 +101,7 @@ static inline void omap_init_mbox(void) { }
 
 #if defined(CONFIG_OMAP_STI)
 
-#define OMAP1_STI_BASE         IO_ADDRESS(0xfffea000)
+#define OMAP1_STI_BASE         0xfffea000
 #define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
 
 static struct resource sti_resources[] = {
index 2baeaeb0c9004d2038a7c1fde8b398068de77810..7de7c69155840f2e84fddc23574bb9d74546afe5 100644 (file)
@@ -103,30 +103,6 @@ static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
 { }
 #endif
 
-static int omap1_mcbsp_check(unsigned int id)
-{
-       /* REVISIT: Check correctly for number of registered McBSPs */
-       if (cpu_is_omap730()) {
-               if (id > OMAP_MAX_MCBSP_COUNT - 2) {
-                      printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
-                               id + 1);
-                      return -ENODEV;
-               }
-               return 0;
-       }
-
-       if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
-               if (id > OMAP_MAX_MCBSP_COUNT - 1) {
-                       printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
-                               id + 1);
-                       return -ENODEV;
-               }
-               return 0;
-       }
-
-       return -ENODEV;
-}
-
 static void omap1_mcbsp_request(unsigned int id)
 {
        /*
@@ -151,7 +127,6 @@ static void omap1_mcbsp_free(unsigned int id)
 }
 
 static struct omap_mcbsp_ops omap1_mcbsp_ops = {
-       .check          = omap1_mcbsp_check,
        .request        = omap1_mcbsp_request,
        .free           = omap1_mcbsp_free,
 };
@@ -160,7 +135,6 @@ static struct omap_mcbsp_ops omap1_mcbsp_ops = {
 static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
        {
                .phys_base      = OMAP730_MCBSP1_BASE,
-               .virt_base      = io_p2v(OMAP730_MCBSP1_BASE),
                .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
                .rx_irq         = INT_730_McBSP1RX,
@@ -169,7 +143,6 @@ static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
        },
        {
                .phys_base      = OMAP730_MCBSP2_BASE,
-               .virt_base      = io_p2v(OMAP730_MCBSP2_BASE),
                .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
                .rx_irq         = INT_730_McBSP2RX,
@@ -187,7 +160,6 @@ static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
        {
                .phys_base      = OMAP1510_MCBSP1_BASE,
-               .virt_base      = OMAP1510_MCBSP1_BASE,
                .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
                .rx_irq         = INT_McBSP1RX,
@@ -197,7 +169,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
                },
        {
                .phys_base      = OMAP1510_MCBSP2_BASE,
-               .virt_base      = io_p2v(OMAP1510_MCBSP2_BASE),
                .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,
                .rx_irq         = INT_1510_SPI_RX,
@@ -206,7 +177,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
        },
        {
                .phys_base      = OMAP1510_MCBSP3_BASE,
-               .virt_base      = OMAP1510_MCBSP3_BASE,
                .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
                .rx_irq         = INT_McBSP3RX,
@@ -225,7 +195,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
        {
                .phys_base      = OMAP1610_MCBSP1_BASE,
-               .virt_base      = OMAP1610_MCBSP1_BASE,
                .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
                .rx_irq         = INT_McBSP1RX,
@@ -235,7 +204,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
        },
        {
                .phys_base      = OMAP1610_MCBSP2_BASE,
-               .virt_base      = io_p2v(OMAP1610_MCBSP2_BASE),
                .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,
                .rx_irq         = INT_1610_McBSP2_RX,
@@ -244,7 +212,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
        },
        {
                .phys_base      = OMAP1610_MCBSP3_BASE,
-               .virt_base      = OMAP1610_MCBSP3_BASE,
                .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
                .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
                .rx_irq         = INT_McBSP3RX,
@@ -270,6 +237,18 @@ int __init omap1_mcbsp_init(void)
                }
        }
 
+       if (cpu_is_omap730())
+               omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ;
+       if (cpu_is_omap15xx())
+               omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ;
+       if (cpu_is_omap16xx())
+               omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ;
+
+       mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
+                                                               GFP_KERNEL);
+       if (!mcbsp_ptr)
+               return -ENOMEM;
+
        if (cpu_is_omap730())
                omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata,
                                                OMAP730_MCBSP_PDATA_SZ);
index aefc967fc003fe2e19e1244fb9fb40ef70589ae0..528691d5cb51ed76899041c6285774ae2d608bd6 100644 (file)
@@ -67,8 +67,8 @@ static void __init omap_serial_reset(struct plat_serial8250_port *p)
 
 static struct plat_serial8250_port serial_platform_data[] = {
        {
-               .membase        = (char*)IO_ADDRESS(OMAP_UART1_BASE),
-               .mapbase        = (unsigned long)OMAP_UART1_BASE,
+               .membase        = IO_ADDRESS(OMAP_UART1_BASE),
+               .mapbase        = OMAP_UART1_BASE,
                .irq            = INT_UART1,
                .flags          = UPF_BOOT_AUTOCONF,
                .iotype         = UPIO_MEM,
@@ -76,8 +76,8 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .uartclk        = OMAP16XX_BASE_BAUD * 16,
        },
        {
-               .membase        = (char*)IO_ADDRESS(OMAP_UART2_BASE),
-               .mapbase        = (unsigned long)OMAP_UART2_BASE,
+               .membase        = IO_ADDRESS(OMAP_UART2_BASE),
+               .mapbase        = OMAP_UART2_BASE,
                .irq            = INT_UART2,
                .flags          = UPF_BOOT_AUTOCONF,
                .iotype         = UPIO_MEM,
@@ -85,8 +85,8 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .uartclk        = OMAP16XX_BASE_BAUD * 16,
        },
        {
-               .membase        = (char*)IO_ADDRESS(OMAP_UART3_BASE),
-               .mapbase        = (unsigned long)OMAP_UART3_BASE,
+               .membase        = IO_ADDRESS(OMAP_UART3_BASE),
+               .mapbase        = OMAP_UART3_BASE,
                .irq            = INT_UART3,
                .flags          = UPF_BOOT_AUTOCONF,
                .iotype         = UPIO_MEM,
index 7069c9d536f1b07ad07460a9909cb050be8d013c..4832fcc7d04a14be864b663590aaf6b2b1258abb 100644 (file)
@@ -15,8 +15,17 @@ config ARCH_OMAP2430
        bool "OMAP2430 support"
        depends on ARCH_OMAP24XX
 
+config ARCH_OMAP34XX
+       bool "OMAP34xx Based System"
+       depends on ARCH_OMAP3
+
+config ARCH_OMAP3430
+       bool "OMAP3430 support"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+       select ARCH_OMAP_OTG
+
 comment "OMAP Board Type"
-       depends on ARCH_OMAP2
+       depends on ARCH_OMAP2 || ARCH_OMAP3
 
 config MACH_OMAP_GENERIC
        bool "Generic OMAP board"
@@ -35,3 +44,14 @@ config MACH_OMAP_2430SDP
        bool "OMAP 2430 SDP board"
        depends on ARCH_OMAP2 && ARCH_OMAP24XX
 
+config MACH_OMAP3_BEAGLE
+       bool "OMAP3 BEAGLE board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP_LDP
+       bool "OMAP3 LDP board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OVERO
+       bool "Gumstix Overo board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
index 93ee990618ef32b0905dd5de7bc515aa5a70c14d..c69392372c99890f9c50f96e5c7a556b5bef98a6 100644 (file)
@@ -4,16 +4,21 @@
 
 # Common support
 obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
-               devices.o serial.o gpmc.o timer-gp.o
+               devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
+               clockdomain.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
 # Functions loaded to SRAM
 obj-$(CONFIG_ARCH_OMAP2420)            += sram242x.o
 obj-$(CONFIG_ARCH_OMAP2430)            += sram243x.o
+obj-$(CONFIG_ARCH_OMAP3)               += sram34xx.o
 
 # Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
+ifeq ($(CONFIG_PM),y)
+obj-y                                  += pm.o
+obj-$(CONFIG_ARCH_OMAP24XX)            += sleep24xx.o
+endif
 
 # Clock framework
 obj-$(CONFIG_ARCH_OMAP2)               += clock24xx.o
@@ -24,4 +29,7 @@ obj-$(CONFIG_MACH_OMAP_GENERIC)               += board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)             += board-h4.o
 obj-$(CONFIG_MACH_OMAP_2430SDP)                += board-2430sdp.o
 obj-$(CONFIG_MACH_OMAP_APOLLON)                += board-apollon.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE)                += board-omap3beagle.o
+obj-$(CONFIG_MACH_OMAP_LDP)            += board-ldp.o
+obj-$(CONFIG_MACH_OVERO)               += board-overo.o
 
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
new file mode 100644 (file)
index 0000000..1ea5998
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/arm/mach-omap2/board-ldp.c
+ *
+ * Copyright (C) 2008 Texas Instruments Inc.
+ * Nishant Kamat <nskamat@ti.com>
+ *
+ * Modified from mach-omap2/board-3430sdp.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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-ldp.h>
+#include <mach/mcspi.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/gpmc.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <mach/control.h>
+
+static void __init omap_ldp_init_irq(void)
+{
+       omap2_init_common_hw();
+       omap_init_irq();
+       omap_gpio_init();
+}
+
+static struct omap_uart_config ldp_uart_config __initdata = {
+       .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel ldp_config[] __initdata = {
+       { OMAP_TAG_UART,        &ldp_uart_config },
+};
+
+static int __init omap_i2c_init(void)
+{
+       omap_register_i2c_bus(1, 2600, NULL, 0);
+       omap_register_i2c_bus(2, 400, NULL, 0);
+       omap_register_i2c_bus(3, 400, NULL, 0);
+       return 0;
+}
+
+static void __init omap_ldp_init(void)
+{
+       omap_i2c_init();
+       omap_board_config = ldp_config;
+       omap_board_config_size = ARRAY_SIZE(ldp_config);
+       omap_serial_init();
+}
+
+static void __init omap_ldp_map_io(void)
+{
+       omap2_set_globals_343x();
+       omap2_map_common_io();
+}
+
+MACHINE_START(OMAP_LDP, "OMAP LDP board")
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = omap_ldp_map_io,
+       .init_irq       = omap_ldp_init_irq,
+       .init_machine   = omap_ldp_init,
+       .timer          = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
new file mode 100644 (file)
index 0000000..baa7967
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3beagle.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+
+
+#define GPMC_CS0_BASE  0x60
+#define GPMC_CS_SIZE   0x30
+
+#define NAND_BLOCK_SIZE                SZ_128K
+
+static struct mtd_partition omap3beagle_nand_partitions[] = {
+       /* All the partition sizes are listed in terms of NAND block size */
+       {
+               .name           = "X-Loader",
+               .offset         = 0,
+               .size           = 4 * NAND_BLOCK_SIZE,
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
+       {
+               .name           = "U-Boot",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
+               .size           = 15 * NAND_BLOCK_SIZE,
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
+       {
+               .name           = "U-Boot Env",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x260000 */
+               .size           = 1 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "Kernel",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
+               .size           = 32 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "File System",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x680000 */
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct omap_nand_platform_data omap3beagle_nand_data = {
+       .options        = NAND_BUSWIDTH_16,
+       .parts          = omap3beagle_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(omap3beagle_nand_partitions),
+       .dma_channel    = -1,           /* disable DMA in OMAP NAND driver */
+       .nand_setup     = NULL,
+       .dev_ready      = NULL,
+};
+
+static struct resource omap3beagle_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device omap3beagle_nand_device = {
+       .name           = "omap2-nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &omap3beagle_nand_data,
+       },
+       .num_resources  = 1,
+       .resource       = &omap3beagle_nand_resource,
+};
+
+static struct omap_uart_config omap3_beagle_uart_config __initdata = {
+       .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static void __init omap3_beagle_init_irq(void)
+{
+       omap2_init_common_hw();
+       omap_init_irq();
+       omap_gpio_init();
+}
+
+static struct platform_device omap3_beagle_lcd_device = {
+       .name           = "omap3beagle_lcd",
+       .id             = -1,
+};
+
+static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
+       .ctrl_name      = "internal",
+};
+
+static struct gpio_led gpio_leds[] = {
+       {
+               .name                   = "beagleboard::usr0",
+               .default_trigger        = "heartbeat",
+               .gpio                   = 150,
+       },
+       {
+               .name                   = "beagleboard::usr1",
+               .default_trigger        = "mmc0",
+               .gpio                   = 149,
+       },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+       .leds           = gpio_leds,
+       .num_leds       = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gpio_led_info,
+       },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+       {
+               .code                   = BTN_EXTRA,
+               .gpio                   = 7,
+               .desc                   = "user",
+               .wakeup                 = 1,
+       },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+       .buttons        = gpio_buttons,
+       .nbuttons       = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+       .name   = "gpio-keys",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gpio_key_info,
+       },
+};
+
+static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
+       { OMAP_TAG_UART,        &omap3_beagle_uart_config },
+       { OMAP_TAG_LCD,         &omap3_beagle_lcd_config },
+};
+
+static struct platform_device *omap3_beagle_devices[] __initdata = {
+       &omap3_beagle_lcd_device,
+       &leds_gpio,
+       &keys_gpio,
+};
+
+static void __init omap3beagle_flash_init(void)
+{
+       u8 cs = 0;
+       u8 nandcs = GPMC_CS_NUM + 1;
+
+       u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+       /* find out the chip-select on which NAND exists */
+       while (cs < GPMC_CS_NUM) {
+               u32 ret = 0;
+               ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+               if ((ret & 0xC00) == 0x800) {
+                       printk(KERN_INFO "Found NAND on CS%d\n", cs);
+                       if (nandcs > GPMC_CS_NUM)
+                               nandcs = cs;
+               }
+               cs++;
+       }
+
+       if (nandcs > GPMC_CS_NUM) {
+               printk(KERN_INFO "NAND: Unable to find configuration "
+                                "in GPMC\n ");
+               return;
+       }
+
+       if (nandcs < GPMC_CS_NUM) {
+               omap3beagle_nand_data.cs = nandcs;
+               omap3beagle_nand_data.gpmc_cs_baseaddr = (void *)
+                       (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+               omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
+
+               printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+               if (platform_device_register(&omap3beagle_nand_device) < 0)
+                       printk(KERN_ERR "Unable to register NAND device\n");
+       }
+}
+
+static void __init omap3_beagle_init(void)
+{
+       platform_add_devices(omap3_beagle_devices,
+                       ARRAY_SIZE(omap3_beagle_devices));
+       omap_board_config = omap3_beagle_config;
+       omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
+       omap_serial_init();
+       omap3beagle_flash_init();
+}
+
+static void __init omap3_beagle_map_io(void)
+{
+       omap2_set_globals_343x();
+       omap2_map_common_io();
+}
+
+MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
+       /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = omap3_beagle_map_io,
+       .init_irq       = omap3_beagle_init_irq,
+       .init_machine   = omap3_beagle_init,
+       .timer          = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
new file mode 100644 (file)
index 0000000..e09aa59
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * board-overo.c (Gumstix Overo)
+ *
+ * Initial code: Steve Sakoman <steve@sakoman.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/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-overo.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/gpio.h>
+#include <mach/gpmc.h>
+#include <mach/hardware.h>
+#include <mach/nand.h>
+
+#define NAND_BLOCK_SIZE SZ_128K
+#define GPMC_CS0_BASE  0x60
+#define GPMC_CS_SIZE   0x30
+
+static struct mtd_partition overo_nand_partitions[] = {
+       {
+               .name           = "xloader",
+               .offset         = 0,                    /* Offset = 0x00000 */
+               .size           = 4 * NAND_BLOCK_SIZE,
+               .mask_flags     = MTD_WRITEABLE
+       },
+       {
+               .name           = "uboot",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
+               .size           = 14 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "uboot environment",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x240000 */
+               .size           = 2 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "linux",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
+               .size           = 32 * NAND_BLOCK_SIZE,
+       },
+       {
+               .name           = "rootfs",
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x680000 */
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct omap_nand_platform_data overo_nand_data = {
+       .parts = overo_nand_partitions,
+       .nr_parts = ARRAY_SIZE(overo_nand_partitions),
+       .dma_channel = -1,      /* disable DMA in OMAP NAND driver */
+};
+
+static struct resource overo_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device overo_nand_device = {
+       .name           = "omap2-nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &overo_nand_data,
+       },
+       .num_resources  = 1,
+       .resource       = &overo_nand_resource,
+};
+
+
+static void __init overo_flash_init(void)
+{
+       u8 cs = 0;
+       u8 nandcs = GPMC_CS_NUM + 1;
+
+       u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+       /* find out the chip-select on which NAND exists */
+       while (cs < GPMC_CS_NUM) {
+               u32 ret = 0;
+               ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+               if ((ret & 0xC00) == 0x800) {
+                       printk(KERN_INFO "Found NAND on CS%d\n", cs);
+                       if (nandcs > GPMC_CS_NUM)
+                               nandcs = cs;
+               }
+               cs++;
+       }
+
+       if (nandcs > GPMC_CS_NUM) {
+               printk(KERN_INFO "NAND: Unable to find configuration "
+                                "in GPMC\n ");
+               return;
+       }
+
+       if (nandcs < GPMC_CS_NUM) {
+               overo_nand_data.cs = nandcs;
+               overo_nand_data.gpmc_cs_baseaddr = (void *)
+                       (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+               overo_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
+
+               printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+               if (platform_device_register(&overo_nand_device) < 0)
+                       printk(KERN_ERR "Unable to register NAND device\n");
+       }
+}
+static struct omap_uart_config overo_uart_config __initdata = {
+       .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static int __init overo_i2c_init(void)
+{
+       /* i2c2 pins are used for gpio */
+       omap_register_i2c_bus(3, 400, NULL, 0);
+       return 0;
+}
+
+static void __init overo_init_irq(void)
+{
+       omap2_init_common_hw();
+       omap_init_irq();
+       omap_gpio_init();
+}
+
+static struct platform_device overo_lcd_device = {
+       .name           = "overo_lcd",
+       .id             = -1,
+};
+
+static struct omap_lcd_config overo_lcd_config __initdata = {
+       .ctrl_name      = "internal",
+};
+
+static struct omap_board_config_kernel overo_config[] __initdata = {
+       { OMAP_TAG_UART,        &overo_uart_config },
+       { OMAP_TAG_LCD,         &overo_lcd_config },
+};
+
+static struct platform_device *overo_devices[] __initdata = {
+       &overo_lcd_device,
+};
+
+static void __init overo_init(void)
+{
+       overo_i2c_init();
+       platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
+       omap_board_config = overo_config;
+       omap_board_config_size = ARRAY_SIZE(overo_config);
+       omap_serial_init();
+       overo_flash_init();
+
+       if ((gpio_request(OVERO_GPIO_W2W_NRESET,
+                         "OVERO_GPIO_W2W_NRESET") == 0) &&
+           (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) {
+               gpio_export(OVERO_GPIO_W2W_NRESET, 0);
+               gpio_set_value(OVERO_GPIO_W2W_NRESET, 0);
+               udelay(10);
+               gpio_set_value(OVERO_GPIO_W2W_NRESET, 1);
+       } else {
+               printk(KERN_ERR "could not obtain gpio for "
+                                       "OVERO_GPIO_W2W_NRESET\n");
+       }
+
+       if ((gpio_request(OVERO_GPIO_BT_XGATE, "OVERO_GPIO_BT_XGATE") == 0) &&
+           (gpio_direction_output(OVERO_GPIO_BT_XGATE, 0) == 0))
+               gpio_export(OVERO_GPIO_BT_XGATE, 0);
+       else
+               printk(KERN_ERR "could not obtain gpio for OVERO_GPIO_BT_XGATE\n");
+
+       if ((gpio_request(OVERO_GPIO_BT_NRESET, "OVERO_GPIO_BT_NRESET") == 0) &&
+           (gpio_direction_output(OVERO_GPIO_BT_NRESET, 1) == 0)) {
+               gpio_export(OVERO_GPIO_BT_NRESET, 0);
+               gpio_set_value(OVERO_GPIO_BT_NRESET, 0);
+               mdelay(6);
+               gpio_set_value(OVERO_GPIO_BT_NRESET, 1);
+       } else {
+               printk(KERN_ERR "could not obtain gpio for "
+                                       "OVERO_GPIO_BT_NRESET\n");
+       }
+
+       if ((gpio_request(OVERO_GPIO_USBH_CPEN, "OVERO_GPIO_USBH_CPEN") == 0) &&
+           (gpio_direction_output(OVERO_GPIO_USBH_CPEN, 1) == 0))
+               gpio_export(OVERO_GPIO_USBH_CPEN, 0);
+       else
+               printk(KERN_ERR "could not obtain gpio for "
+                                       "OVERO_GPIO_USBH_CPEN\n");
+
+       if ((gpio_request(OVERO_GPIO_USBH_NRESET,
+                         "OVERO_GPIO_USBH_NRESET") == 0) &&
+           (gpio_direction_output(OVERO_GPIO_USBH_NRESET, 1) == 0))
+               gpio_export(OVERO_GPIO_USBH_NRESET, 0);
+       else
+               printk(KERN_ERR "could not obtain gpio for "
+                                       "OVERO_GPIO_USBH_NRESET\n");
+}
+
+static void __init overo_map_io(void)
+{
+       omap2_set_globals_343x();
+       omap2_map_common_io();
+}
+
+MACHINE_START(OVERO, "Gumstix Overo")
+       .phys_io        = 0x48000000,
+       .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
+       .boot_params    = 0x80000100,
+       .map_io         = overo_map_io,
+       .init_irq       = overo_init_irq,
+       .init_machine   = overo_init,
+       .timer          = &omap_timer,
+MACHINE_END
index 97cde3d3611dede6c2f67b0091f8a0c4ce76db55..ad721e0cbf7a1ded6c54ab2212efb4a5da1f281e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/bitops.h>
 
 #include <mach/clock.h>
+#include <mach/clockdomain.h>
 #include <mach/sram.h>
 #include <mach/cpu.h>
 #include <asm/div64.h>
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
- * Omap2 specific clock functions
+ * OMAP2/3 specific clock functions
  *-------------------------------------------------------------------------*/
 
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk.  Intended to be
+ * called during clk_register().  No return value.
+ */
+void omap2_init_clk_clkdm(struct clk *clk)
+{
+       struct clockdomain *clkdm;
+
+       if (!clk->clkdm_name)
+               return;
+
+       clkdm = clkdm_lookup(clk->clkdm_name);
+       if (clkdm) {
+               pr_debug("clock: associated clk %s to clkdm %s\n",
+                        clk->name, clk->clkdm_name);
+               clk->clkdm = clkdm;
+       } else {
+               pr_debug("clock: could not associate clk %s to "
+                        "clkdm %s\n", clk->name, clk->clkdm_name);
+       }
+}
+
 /**
  * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
  * @clk: OMAP clock struct ptr to use
@@ -250,7 +277,7 @@ int _omap2_clk_enable(struct clk *clk)
        if (clk->enable)
                return clk->enable(clk);
 
-       if (unlikely(clk->enable_reg == 0)) {
+       if (unlikely(clk->enable_reg == NULL)) {
                printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
                       clk->name);
                return 0; /* REVISIT: -EINVAL */
@@ -282,7 +309,7 @@ void _omap2_clk_disable(struct clk *clk)
                return;
        }
 
-       if (clk->enable_reg == 0) {
+       if (clk->enable_reg == NULL) {
                /*
                 * 'Independent' here refers to a clock which is not
                 * controlled by its parent.
@@ -307,6 +334,9 @@ void omap2_clk_disable(struct clk *clk)
                _omap2_clk_disable(clk);
                if (likely((u32)clk->parent))
                        omap2_clk_disable(clk->parent);
+               if (clk->clkdm)
+                       omap2_clkdm_clk_disable(clk->clkdm, clk);
+
        }
 }
 
@@ -323,11 +353,19 @@ int omap2_clk_enable(struct clk *clk)
                        return ret;
                }
 
+               if (clk->clkdm)
+                       omap2_clkdm_clk_enable(clk->clkdm, clk);
+
                ret = _omap2_clk_enable(clk);
 
-               if (unlikely(ret != 0) && clk->parent) {
-                       omap2_clk_disable(clk->parent);
-                       clk->usecount--;
+               if (unlikely(ret != 0)) {
+                       if (clk->clkdm)
+                               omap2_clkdm_clk_disable(clk->clkdm, clk);
+
+                       if (clk->parent) {
+                               omap2_clk_disable(clk->parent);
+                               clk->usecount--;
+                       }
                }
        }
 
@@ -476,7 +514,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
 /* Given a clock and a rate apply a clock specific rounding function */
 long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
 {
-       if (clk->round_rate != 0)
+       if (clk->round_rate != NULL)
                return clk->round_rate(clk, rate);
 
        if (clk->flags & RATE_FIXED)
@@ -565,7 +603,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
  */
 void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
 {
-       if (unlikely((clk->clksel_reg == 0) || (clk->clksel_mask == 0)))
+       if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
                return NULL;
 
        *field_mask = clk->clksel_mask;
@@ -585,7 +623,7 @@ u32 omap2_clksel_get_divisor(struct clk *clk)
        void __iomem *div_addr;
 
        div_addr = omap2_get_clksel(clk, &field_mask);
-       if (div_addr == 0)
+       if (div_addr == NULL)
                return 0;
 
        field_val = __raw_readl(div_addr) & field_mask;
@@ -604,7 +642,7 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
                return -EINVAL;
 
        div_addr = omap2_get_clksel(clk, &field_mask);
-       if (div_addr == 0)
+       if (div_addr == NULL)
                return -EINVAL;
 
        field_val = omap2_divisor_to_clksel(clk, new_div);
@@ -642,7 +680,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
                return -EINVAL;
 
        /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
-       if (clk->set_rate != 0)
+       if (clk->set_rate != NULL)
                ret = clk->set_rate(clk, rate);
 
        if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
@@ -663,7 +701,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
        const struct clksel_rate *clkr;
 
        *parent_div = 0;
-       *src_addr = 0;
+       *src_addr = NULL;
 
        clks = omap2_get_clksel_by_parent(clk, src_clk);
        if (clks == NULL)
@@ -704,7 +742,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 
        field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
                                               &field_mask, clk, &parent_div);
-       if (src_addr == 0)
+       if (src_addr == NULL)
                return -EINVAL;
 
        if (clk->usecount > 0)
index 626e5fa93b6ad3a9fd6e79164d9092dc29c4935d..1fb330e0847d868bb6ac76fb6de806c1b20a93b7 100644 (file)
@@ -21,6 +21,7 @@
 /* The maximum error between a target DPLL rate and the rounded rate in Hz */
 #define DEFAULT_DPLL_RATE_TOLERANCE    50000
 
+int omap2_clk_init(void);
 int omap2_clk_enable(struct clk *clk);
 void omap2_clk_disable(struct clk *clk);
 long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
@@ -36,6 +37,7 @@ void omap2_clk_disable_unused(struct clk *clk);
 #endif
 
 void omap2_clksel_recalc(struct clk *clk);
+void omap2_init_clk_clkdm(struct clk *clk);
 void omap2_init_clksel_parent(struct clk *clk);
 u32 omap2_clksel_get_divisor(struct clk *clk);
 u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
index be4e25554e05dfe0ad608a837f763164bf3275df..242a19d86ccd025f1a36d6baede741e0a7b5d03c 100644 (file)
@@ -626,6 +626,7 @@ static struct clk func_32k_ck = {
        .rate           = 32000,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &propagate_rate,
 };
 
@@ -634,17 +635,19 @@ static struct clk osc_ck = {              /* (*12, *13, 19.2, *26, 38.4)MHz */
        .name           = "osc_ck",
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .enable         = &omap2_enable_osc_ck,
        .disable        = &omap2_disable_osc_ck,
        .recalc         = &omap2_osc_clk_recalc,
 };
 
-/* With out modem likely 12MHz, with modem likely 13MHz */
+/* Without modem likely 12MHz, with modem likely 13MHz */
 static struct clk sys_ck = {           /* (*12, *13, 19.2, 26, 38.4)MHz */
        .name           = "sys_ck",             /* ~ ref_clk also */
        .parent         = &osc_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                ALWAYS_ENABLED | RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &omap2_sys_clk_recalc,
 };
 
@@ -653,6 +656,7 @@ static struct clk alt_ck = {                /* Typical 54M or 48M, may not exist */
        .rate           = 54000000,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &propagate_rate,
 };
 
@@ -684,6 +688,7 @@ static struct clk dpll_ck = {
        .dpll_data      = &dpll_dd,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &omap2_dpllcore_recalc,
        .set_rate       = &omap2_reprogram_dpllcore,
 };
@@ -694,6 +699,7 @@ static struct clk apll96_ck = {
        .rate           = 96000000,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
        .enable_bit     = OMAP24XX_EN_96M_PLL_SHIFT,
        .enable         = &omap2_clk_fixed_enable,
@@ -707,6 +713,7 @@ static struct clk apll54_ck = {
        .rate           = 54000000,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
        .enable_bit     = OMAP24XX_EN_54M_PLL_SHIFT,
        .enable         = &omap2_clk_fixed_enable,
@@ -741,6 +748,7 @@ static struct clk func_54m_ck = {
        .parent         = &apll54_ck,   /* can also be alt_clk */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "wkup_clkdm",
        .init           = &omap2_init_clksel_parent,
        .clksel_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
        .clksel_mask    = OMAP24XX_54M_SOURCE,
@@ -753,6 +761,7 @@ static struct clk core_ck = {
        .parent         = &dpll_ck,             /* can also be 32k */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                ALWAYS_ENABLED | RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -779,6 +788,7 @@ static struct clk func_96m_ck = {
        .parent         = &apll96_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "wkup_clkdm",
        .init           = &omap2_init_clksel_parent,
        .clksel_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
        .clksel_mask    = OMAP2430_96M_SOURCE,
@@ -811,6 +821,7 @@ static struct clk func_48m_ck = {
        .parent         = &apll96_ck,    /* 96M or Alt */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "wkup_clkdm",
        .init           = &omap2_init_clksel_parent,
        .clksel_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
        .clksel_mask    = OMAP24XX_48M_SOURCE,
@@ -826,6 +837,7 @@ static struct clk func_12m_ck = {
        .fixed_div      = 4,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &omap2_fixed_divisor_recalc,
 };
 
@@ -878,6 +890,7 @@ static struct clk sys_clkout_src = {
        .parent         = &func_54m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP24XX_PRCM_CLKOUT_CTRL,
        .enable_bit     = OMAP24XX_CLKOUT_EN_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -908,6 +921,7 @@ static struct clk sys_clkout = {
        .parent         = &sys_clkout_src,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "wkup_clkdm",
        .clksel_reg     = OMAP24XX_PRCM_CLKOUT_CTRL,
        .clksel_mask    = OMAP24XX_CLKOUT_DIV_MASK,
        .clksel         = sys_clkout_clksel,
@@ -921,6 +935,7 @@ static struct clk sys_clkout2_src = {
        .name           = "sys_clkout2_src",
        .parent         = &func_54m_ck,
        .flags          = CLOCK_IN_OMAP242X | RATE_PROPAGATES,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP24XX_PRCM_CLKOUT_CTRL,
        .enable_bit     = OMAP2420_CLKOUT2_EN_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -942,6 +957,7 @@ static struct clk sys_clkout2 = {
        .name           = "sys_clkout2",
        .parent         = &sys_clkout2_src,
        .flags          = CLOCK_IN_OMAP242X | PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "wkup_clkdm",
        .clksel_reg     = OMAP24XX_PRCM_CLKOUT_CTRL,
        .clksel_mask    = OMAP2420_CLKOUT2_DIV_MASK,
        .clksel         = sys_clkout2_clksel,
@@ -954,6 +970,7 @@ static struct clk emul_ck = {
        .name           = "emul_ck",
        .parent         = &func_54m_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP24XX_PRCM_CLKEMUL_CTRL,
        .enable_bit     = OMAP24XX_EMULATION_EN_SHIFT,
        .recalc         = &followparent_recalc,
@@ -990,12 +1007,13 @@ static struct clk mpu_ck = {     /* Control cpu */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                ALWAYS_ENABLED | DELAYED_APP |
                                CONFIG_PARTICIPANT | RATE_PROPAGATES,
+       .clkdm_name     = "mpu_clkdm",
        .init           = &omap2_init_clksel_parent,
        .clksel_reg     = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
        .clksel_mask    = OMAP24XX_CLKSEL_MPU_MASK,
        .clksel         = mpu_clksel,
        .recalc         = &omap2_clksel_recalc,
-       .round_rate     = &omap2_clksel_round_rate,
+       .round_rate     = &omap2_clksel_round_rate,
        .set_rate       = &omap2_clksel_set_rate
 };
 
@@ -1031,6 +1049,7 @@ static struct clk dsp_fck = {
        .parent         = &core_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP |
                                CONFIG_PARTICIPANT | RATE_PROPAGATES,
+       .clkdm_name     = "dsp_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
@@ -1054,10 +1073,7 @@ static const struct clksel dsp_irate_ick_clksel[] = {
        { .parent = NULL }
 };
 
-/*
- * This clock does not exist as such in the TRM, but is added to
- * separate source selection from  XXX
- */
+/* This clock does not exist as such in the TRM. */
 static struct clk dsp_irate_ick = {
        .name           = "dsp_irate_ick",
        .parent         = &dsp_fck,
@@ -1089,11 +1105,17 @@ static struct clk iva2_1_ick = {
        .enable_bit     = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
 };
 
+/*
+ * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
+ * the C54x, but which is contained in the DSP powerdomain.  Does not
+ * exist on later OMAPs.
+ */
 static struct clk iva1_ifck = {
        .name           = "iva1_ifck",
        .parent         = &core_ck,
        .flags          = CLOCK_IN_OMAP242X | CONFIG_PARTICIPANT |
                                RATE_PROPAGATES | DELAYED_APP,
+       .clkdm_name     = "iva1_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP2420_EN_IVA_COP_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
@@ -1109,6 +1131,7 @@ static struct clk iva1_mpu_int_ifck = {
        .name           = "iva1_mpu_int_ifck",
        .parent         = &iva1_ifck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "iva1_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP2420_EN_IVA_MPU_SHIFT,
        .fixed_div      = 2,
@@ -1156,6 +1179,7 @@ static struct clk core_l3_ck = {  /* Used for ick and fck, interconnect */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                ALWAYS_ENABLED | DELAYED_APP |
                                CONFIG_PARTICIPANT | RATE_PROPAGATES,
+       .clkdm_name     = "core_l3_clkdm",
        .clksel_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
        .clksel_mask    = OMAP24XX_CLKSEL_L3_MASK,
        .clksel         = core_l3_clksel,
@@ -1177,11 +1201,13 @@ static const struct clksel usb_l4_ick_clksel[] = {
        { .parent = NULL },
 };
 
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
 static struct clk usb_l4_ick = {       /* FS-USB interface clock */
        .name           = "usb_l4_ick",
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                DELAYED_APP | CONFIG_PARTICIPANT,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP24XX_EN_USB_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
@@ -1192,11 +1218,43 @@ static struct clk usb_l4_ick = {        /* FS-USB interface clock */
        .set_rate       = &omap2_clksel_set_rate
 };
 
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks.  Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+       { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+       { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+       { .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+       { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+       { .parent = NULL }
+};
+
+static struct clk l4_ck = {            /* used both as an ick and fck */
+       .name           = "l4_ck",
+       .parent         = &core_l3_ck,
+       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+                               ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES,
+       .clkdm_name     = "core_l4_clkdm",
+       .clksel_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+       .clksel_mask    = OMAP24XX_CLKSEL_L4_MASK,
+       .clksel         = l4_clksel,
+       .recalc         = &omap2_clksel_recalc,
+       .round_rate     = &omap2_clksel_round_rate,
+       .set_rate       = &omap2_clksel_set_rate
+};
+
 /*
  * SSI is in L3 management domain, its direct parent is core not l3,
  * many core power domain entities are grouped into the L3 clock
  * domain.
- * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
  *
  * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
  */
@@ -1221,6 +1279,7 @@ static struct clk ssi_ssr_sst_fck = {
        .parent         = &core_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                DELAYED_APP,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP24XX_EN_SSI_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
@@ -1231,6 +1290,7 @@ static struct clk ssi_ssr_sst_fck = {
        .set_rate       = &omap2_clksel_set_rate
 };
 
+
 /*
  * GFX clock domain
  *     Clocks:
@@ -1254,6 +1314,7 @@ static struct clk gfx_3d_fck = {
        .name           = "gfx_3d_fck",
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "gfx_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
        .enable_bit     = OMAP24XX_EN_3D_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
@@ -1268,6 +1329,7 @@ static struct clk gfx_2d_fck = {
        .name           = "gfx_2d_fck",
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "gfx_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
        .enable_bit     = OMAP24XX_EN_2D_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
@@ -1282,6 +1344,7 @@ static struct clk gfx_ick = {
        .name           = "gfx_ick",            /* From l3 */
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "gfx_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
        .enable_bit     = OMAP_EN_GFX_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1311,6 +1374,7 @@ static struct clk mdm_ick = {             /* used both as a ick and fck */
        .name           = "mdm_ick",
        .parent         = &core_ck,
        .flags          = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT,
+       .clkdm_name     = "mdm_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
        .enable_bit     = OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
        .clksel_reg     = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
@@ -1325,51 +1389,12 @@ static struct clk mdm_osc_ck = {
        .name           = "mdm_osc_ck",
        .parent         = &osc_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "mdm_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
        .enable_bit     = OMAP2430_EN_OSC_SHIFT,
        .recalc         = &followparent_recalc,
 };
 
-/*
- * L4 clock management domain
- *
- * This domain contains lots of interface clocks from the L4 interface, some
- * functional clocks.  Fixed APLL functional source clocks are managed in
- * this domain.
- */
-static const struct clksel_rate l4_core_l3_rates[] = {
-       { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-       { .div = 2, .val = 2, .flags = RATE_IN_24XX },
-       { .div = 0 }
-};
-
-static const struct clksel l4_clksel[] = {
-       { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
-       { .parent = NULL }
-};
-
-static struct clk l4_ck = {            /* used both as an ick and fck */
-       .name           = "l4_ck",
-       .parent         = &core_l3_ck,
-       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-                               ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES,
-       .clksel_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-       .clksel_mask    = OMAP24XX_CLKSEL_L4_MASK,
-       .clksel         = l4_clksel,
-       .recalc         = &omap2_clksel_recalc,
-       .round_rate     = &omap2_clksel_round_rate,
-       .set_rate       = &omap2_clksel_set_rate
-};
-
-static struct clk ssi_l4_ick = {
-       .name           = "ssi_l4_ick",
-       .parent         = &l4_ck,
-       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
-       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-       .enable_bit     = OMAP24XX_EN_SSI_SHIFT,
-       .recalc         = &followparent_recalc,
-};
-
 /*
  * DSS clock domain
  * CLOCKs:
@@ -1409,6 +1434,7 @@ static struct clk dss_ick = {             /* Enables both L3,L4 ICLK's */
        .name           = "dss_ick",
        .parent         = &l4_ck,       /* really both l3 and l4 */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "dss_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_DSS1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1419,6 +1445,7 @@ static struct clk dss1_fck = {
        .parent         = &core_ck,             /* Core or sys */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                DELAYED_APP,
+       .clkdm_name     = "dss_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_DSS1_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1451,6 +1478,7 @@ static struct clk dss2_fck = {            /* Alt clk used in power management */
        .parent         = &sys_ck,              /* fixed at sys_ck or 48MHz */
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
                                DELAYED_APP,
+       .clkdm_name     = "dss_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_DSS2_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1464,6 +1492,7 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */
        .name           = "dss_54m_fck",        /* 54m tv clk */
        .parent         = &func_54m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "dss_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_TV_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1491,6 +1520,7 @@ static struct clk gpt1_ick = {
        .name           = "gpt1_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP24XX_EN_GPT1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1500,6 +1530,7 @@ static struct clk gpt1_fck = {
        .name           = "gpt1_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP24XX_EN_GPT1_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1515,6 +1546,7 @@ static struct clk gpt2_ick = {
        .name           = "gpt2_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1524,6 +1556,7 @@ static struct clk gpt2_fck = {
        .name           = "gpt2_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT2_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1537,6 +1570,7 @@ static struct clk gpt3_ick = {
        .name           = "gpt3_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1546,6 +1580,7 @@ static struct clk gpt3_fck = {
        .name           = "gpt3_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT3_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1559,6 +1594,7 @@ static struct clk gpt4_ick = {
        .name           = "gpt4_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT4_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1568,6 +1604,7 @@ static struct clk gpt4_fck = {
        .name           = "gpt4_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT4_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1581,6 +1618,7 @@ static struct clk gpt5_ick = {
        .name           = "gpt5_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT5_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1590,6 +1628,7 @@ static struct clk gpt5_fck = {
        .name           = "gpt5_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT5_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1603,6 +1642,7 @@ static struct clk gpt6_ick = {
        .name           = "gpt6_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT6_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1612,6 +1652,7 @@ static struct clk gpt6_fck = {
        .name           = "gpt6_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT6_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1634,6 +1675,7 @@ static struct clk gpt7_fck = {
        .name           = "gpt7_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT7_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1647,6 +1689,7 @@ static struct clk gpt8_ick = {
        .name           = "gpt8_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT8_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1656,6 +1699,7 @@ static struct clk gpt8_fck = {
        .name           = "gpt8_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT8_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1669,6 +1713,7 @@ static struct clk gpt9_ick = {
        .name           = "gpt9_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT9_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1678,6 +1723,7 @@ static struct clk gpt9_fck = {
        .name           = "gpt9_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT9_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1691,6 +1737,7 @@ static struct clk gpt10_ick = {
        .name           = "gpt10_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT10_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1700,6 +1747,7 @@ static struct clk gpt10_fck = {
        .name           = "gpt10_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT10_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1713,6 +1761,7 @@ static struct clk gpt11_ick = {
        .name           = "gpt11_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT11_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1722,6 +1771,7 @@ static struct clk gpt11_fck = {
        .name           = "gpt11_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT11_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1735,6 +1785,7 @@ static struct clk gpt12_ick = {
        .name           = "gpt12_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT12_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1744,6 +1795,7 @@ static struct clk gpt12_fck = {
        .name           = "gpt12_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_GPT12_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -1758,6 +1810,7 @@ static struct clk mcbsp1_ick = {
        .id             = 1,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_MCBSP1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1768,6 +1821,7 @@ static struct clk mcbsp1_fck = {
        .id             = 1,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MCBSP1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1778,6 +1832,7 @@ static struct clk mcbsp2_ick = {
        .id             = 2,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_MCBSP2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1788,6 +1843,7 @@ static struct clk mcbsp2_fck = {
        .id             = 2,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MCBSP2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1798,6 +1854,7 @@ static struct clk mcbsp3_ick = {
        .id             = 3,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MCBSP3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1808,6 +1865,7 @@ static struct clk mcbsp3_fck = {
        .id             = 3,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MCBSP3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1818,6 +1876,7 @@ static struct clk mcbsp4_ick = {
        .id             = 4,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MCBSP4_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1828,6 +1887,7 @@ static struct clk mcbsp4_fck = {
        .id             = 4,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MCBSP4_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1838,6 +1898,7 @@ static struct clk mcbsp5_ick = {
        .id             = 5,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MCBSP5_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1848,6 +1909,7 @@ static struct clk mcbsp5_fck = {
        .id             = 5,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MCBSP5_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1857,6 +1919,7 @@ static struct clk mcspi1_ick = {
        .name           = "mcspi_ick",
        .id             = 1,
        .parent         = &l4_ck,
+       .clkdm_name     = "core_l4_clkdm",
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_MCSPI1_SHIFT,
@@ -1868,6 +1931,7 @@ static struct clk mcspi1_fck = {
        .id             = 1,
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MCSPI1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1878,6 +1942,7 @@ static struct clk mcspi2_ick = {
        .id             = 2,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_MCSPI2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1888,6 +1953,7 @@ static struct clk mcspi2_fck = {
        .id             = 2,
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MCSPI2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1898,6 +1964,7 @@ static struct clk mcspi3_ick = {
        .id             = 3,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MCSPI3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1908,6 +1975,7 @@ static struct clk mcspi3_fck = {
        .id             = 3,
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MCSPI3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1917,6 +1985,7 @@ static struct clk uart1_ick = {
        .name           = "uart1_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_UART1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1926,6 +1995,7 @@ static struct clk uart1_fck = {
        .name           = "uart1_fck",
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_UART1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1935,6 +2005,7 @@ static struct clk uart2_ick = {
        .name           = "uart2_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_UART2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1944,6 +2015,7 @@ static struct clk uart2_fck = {
        .name           = "uart2_fck",
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_UART2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1953,6 +2025,7 @@ static struct clk uart3_ick = {
        .name           = "uart3_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP24XX_EN_UART3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1962,6 +2035,7 @@ static struct clk uart3_fck = {
        .name           = "uart3_fck",
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP24XX_EN_UART3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1971,6 +2045,7 @@ static struct clk gpios_ick = {
        .name           = "gpios_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP24XX_EN_GPIOS_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1980,6 +2055,7 @@ static struct clk gpios_fck = {
        .name           = "gpios_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP24XX_EN_GPIOS_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1989,6 +2065,7 @@ static struct clk mpu_wdt_ick = {
        .name           = "mpu_wdt_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP24XX_EN_MPU_WDT_SHIFT,
        .recalc         = &followparent_recalc,
@@ -1998,6 +2075,7 @@ static struct clk mpu_wdt_fck = {
        .name           = "mpu_wdt_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "wkup_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP24XX_EN_MPU_WDT_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2006,31 +2084,40 @@ static struct clk mpu_wdt_fck = {
 static struct clk sync_32k_ick = {
        .name           = "sync_32k_ick",
        .parent         = &l4_ck,
-       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+                               ENABLE_ON_INIT,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP24XX_EN_32KSYNC_SHIFT,
        .recalc         = &followparent_recalc,
 };
+
 static struct clk wdt1_ick = {
        .name           = "wdt1_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP24XX_EN_WDT1_SHIFT,
        .recalc         = &followparent_recalc,
 };
+
 static struct clk omapctrl_ick = {
        .name           = "omapctrl_ick",
        .parent         = &l4_ck,
-       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+                               ENABLE_ON_INIT,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP24XX_EN_OMAPCTRL_SHIFT,
        .recalc         = &followparent_recalc,
 };
+
 static struct clk icr_ick = {
        .name           = "icr_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP2430_EN_ICR_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2040,15 +2127,22 @@ static struct clk cam_ick = {
        .name           = "cam_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_CAM_SHIFT,
        .recalc         = &followparent_recalc,
 };
 
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
 static struct clk cam_fck = {
        .name           = "cam_fck",
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_CAM_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2058,6 +2152,7 @@ static struct clk mailboxes_ick = {
        .name           = "mailboxes_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_MAILBOXES_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2067,6 +2162,7 @@ static struct clk wdt4_ick = {
        .name           = "wdt4_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_WDT4_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2076,6 +2172,7 @@ static struct clk wdt4_fck = {
        .name           = "wdt4_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_WDT4_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2085,6 +2182,7 @@ static struct clk wdt3_ick = {
        .name           = "wdt3_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP2420_EN_WDT3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2094,6 +2192,7 @@ static struct clk wdt3_fck = {
        .name           = "wdt3_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP2420_EN_WDT3_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2103,6 +2202,7 @@ static struct clk mspro_ick = {
        .name           = "mspro_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_MSPRO_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2112,6 +2212,7 @@ static struct clk mspro_fck = {
        .name           = "mspro_fck",
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_MSPRO_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2121,6 +2222,7 @@ static struct clk mmc_ick = {
        .name           = "mmc_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP2420_EN_MMC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2130,6 +2232,7 @@ static struct clk mmc_fck = {
        .name           = "mmc_fck",
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP2420_EN_MMC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2139,6 +2242,7 @@ static struct clk fac_ick = {
        .name           = "fac_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_FAC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2148,6 +2252,7 @@ static struct clk fac_fck = {
        .name           = "fac_fck",
        .parent         = &func_12m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_FAC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2157,6 +2262,7 @@ static struct clk eac_ick = {
        .name           = "eac_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP2420_EN_EAC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2166,6 +2272,7 @@ static struct clk eac_fck = {
        .name           = "eac_fck",
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP2420_EN_EAC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2175,6 +2282,7 @@ static struct clk hdq_ick = {
        .name           = "hdq_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP24XX_EN_HDQ_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2184,6 +2292,7 @@ static struct clk hdq_fck = {
        .name           = "hdq_fck",
        .parent         = &func_12m_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP24XX_EN_HDQ_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2194,6 +2303,7 @@ static struct clk i2c2_ick = {
        .id             = 2,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP2420_EN_I2C2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2204,6 +2314,7 @@ static struct clk i2c2_fck = {
        .id             = 2,
        .parent         = &func_12m_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP2420_EN_I2C2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2214,6 +2325,7 @@ static struct clk i2chs2_fck = {
        .id             = 2,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_I2CHS2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2224,6 +2336,7 @@ static struct clk i2c1_ick = {
        .id             = 1,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP2420_EN_I2C1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2234,6 +2347,7 @@ static struct clk i2c1_fck = {
        .id             = 1,
        .parent         = &func_12m_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP2420_EN_I2C1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2244,6 +2358,7 @@ static struct clk i2chs1_fck = {
        .id             = 1,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_I2CHS1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2252,7 +2367,9 @@ static struct clk i2chs1_fck = {
 static struct clk gpmc_fck = {
        .name           = "gpmc_fck",
        .parent         = &core_l3_ck,
-       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+       .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+                               ENABLE_ON_INIT,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2260,6 +2377,7 @@ static struct clk sdma_fck = {
        .name           = "sdma_fck",
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2267,6 +2385,7 @@ static struct clk sdma_ick = {
        .name           = "sdma_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2274,6 +2393,7 @@ static struct clk vlynq_ick = {
        .name           = "vlynq_ick",
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP2420_EN_VLYNQ_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2308,6 +2428,7 @@ static struct clk vlynq_fck = {
        .name           = "vlynq_fck",
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP242X | DELAYED_APP,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP2420_EN_VLYNQ_SHIFT,
        .init           = &omap2_init_clksel_parent,
@@ -2323,6 +2444,7 @@ static struct clk sdrc_ick = {
        .name           = "sdrc_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
        .enable_bit     = OMAP2430_EN_SDRC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2332,6 +2454,7 @@ static struct clk des_ick = {
        .name           = "des_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
        .enable_bit     = OMAP24XX_EN_DES_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2341,6 +2464,7 @@ static struct clk sha_ick = {
        .name           = "sha_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
        .enable_bit     = OMAP24XX_EN_SHA_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2350,6 +2474,7 @@ static struct clk rng_ick = {
        .name           = "rng_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
        .enable_bit     = OMAP24XX_EN_RNG_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2359,6 +2484,7 @@ static struct clk aes_ick = {
        .name           = "aes_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
        .enable_bit     = OMAP24XX_EN_AES_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2368,6 +2494,7 @@ static struct clk pka_ick = {
        .name           = "pka_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
        .enable_bit     = OMAP24XX_EN_PKA_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2377,6 +2504,7 @@ static struct clk usb_fck = {
        .name           = "usb_fck",
        .parent         = &func_48m_ck,
        .flags          = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP24XX_EN_USB_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2386,6 +2514,7 @@ static struct clk usbhs_ick = {
        .name           = "usbhs_ick",
        .parent         = &core_l3_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_USBHS_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2396,6 +2525,7 @@ static struct clk mmchs1_ick = {
        .id             = 1,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MMCHS1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2406,6 +2536,7 @@ static struct clk mmchs1_fck = {
        .id             = 1,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l3_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MMCHS1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2416,6 +2547,7 @@ static struct clk mmchs2_ick = {
        .id             = 2,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MMCHS2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2435,6 +2567,7 @@ static struct clk gpio5_ick = {
        .name           = "gpio5_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_GPIO5_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2444,6 +2577,7 @@ static struct clk gpio5_fck = {
        .name           = "gpio5_fck",
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_GPIO5_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2453,6 +2587,7 @@ static struct clk mdm_intc_ick = {
        .name           = "mdm_intc_ick",
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
        .enable_bit     = OMAP2430_EN_MDM_INTC_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2463,6 +2598,7 @@ static struct clk mmchsdb1_fck = {
        .id             = 1,
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MMCHSDB1_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2473,6 +2609,7 @@ static struct clk mmchsdb2_fck = {
        .id             = 2,
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP243X,
+       .clkdm_name     = "core_l4_clkdm",
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
        .enable_bit     = OMAP2430_EN_MMCHSDB2_SHIFT,
        .recalc         = &followparent_recalc,
@@ -2551,7 +2688,6 @@ static struct clk *onchip_24xx_clks[] __initdata = {
        &usb_l4_ick,
        /* L4 domain clocks */
        &l4_ck,                 /* used as both core_l4 and wu_l4 */
-       &ssi_l4_ick,
        /* virtual meta-group clock */
        &virt_prcm_set,
        /* general l4 interface ck, multi-parent functional clk */
index e5b475f21081d8848741114a61200a177787e6d7..084e11082f80c872ada5955a4e4a687a9fefdc0a 100644 (file)
@@ -62,11 +62,14 @@ static void omap3_dpll_recalc(struct clk *clk)
 static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
 {
        const struct dpll_data *dd;
+       u32 v;
 
        dd = clk->dpll_data;
 
-       cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask),
-                       dd->control_reg);
+       v = __raw_readl(dd->control_reg);
+       v &= ~dd->enable_mask;
+       v |= clken_bits << __ffs(dd->enable_mask);
+       __raw_writel(v, dd->control_reg);
 }
 
 /* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
@@ -82,7 +85,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
        state <<= dd->idlest_bit;
        idlest_mask = 1 << dd->idlest_bit;
 
-       while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) &&
+       while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) &&
               i < MAX_DPLL_WAIT_TRIES) {
                i++;
                udelay(1);
@@ -285,7 +288,7 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk)
 
        dd = clk->dpll_data;
 
-       v = cm_read_reg(dd->autoidle_reg);
+       v = __raw_readl(dd->autoidle_reg);
        v &= dd->autoidle_mask;
        v >>= __ffs(dd->autoidle_mask);
 
@@ -304,6 +307,7 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk)
 static void omap3_dpll_allow_idle(struct clk *clk)
 {
        const struct dpll_data *dd;
+       u32 v;
 
        if (!clk || !clk->dpll_data)
                return;
@@ -315,9 +319,10 @@ static void omap3_dpll_allow_idle(struct clk *clk)
         * by writing 0x5 instead of 0x1.  Add some mechanism to
         * optionally enter this mode.
         */
-       cm_rmw_reg_bits(dd->autoidle_mask,
-                       DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask),
-                       dd->autoidle_reg);
+       v = __raw_readl(dd->autoidle_reg);
+       v &= ~dd->autoidle_mask;
+       v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
+       __raw_writel(v, dd->autoidle_reg);
 }
 
 /**
@@ -329,15 +334,17 @@ static void omap3_dpll_allow_idle(struct clk *clk)
 static void omap3_dpll_deny_idle(struct clk *clk)
 {
        const struct dpll_data *dd;
+       u32 v;
 
        if (!clk || !clk->dpll_data)
                return;
 
        dd = clk->dpll_data;
 
-       cm_rmw_reg_bits(dd->autoidle_mask,
-                       DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask),
-                       dd->autoidle_reg);
+       v = __raw_readl(dd->autoidle_reg);
+       v &= ~dd->autoidle_mask;
+       v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
+       __raw_writel(v, dd->autoidle_reg);
 }
 
 /* Clock control for DPLL outputs */
@@ -482,8 +489,10 @@ int __init omap2_clk_init(void)
        for (clkp = onchip_34xx_clks;
             clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks);
             clkp++) {
-               if ((*clkp)->flags & cpu_clkflg)
+               if ((*clkp)->flags & cpu_clkflg) {
                        clk_register(*clkp);
+                       omap2_init_clk_clkdm(*clkp);
+               }
        }
 
        /* REVISIT: Not yet ready for OMAP3 */
index ec664457a11a964b88b5f7cf8dd10d882f082588..c38a8a09692ff3748d24208eca1ee492fe967020 100644 (file)
@@ -478,7 +478,7 @@ static struct clk dpll3_m2_ck = {
 };
 
 static const struct clksel core_ck_clksel[] = {
-       { .parent = &sys_ck,      .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,      .rates = dpll_bypass_rates },
        { .parent = &dpll3_m2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -495,7 +495,7 @@ static struct clk core_ck = {
 };
 
 static const struct clksel dpll3_m2x2_ck_clksel[] = {
-       { .parent = &sys_ck,      .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,      .rates = dpll_bypass_rates },
        { .parent = &dpll3_x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -541,7 +541,7 @@ static struct clk dpll3_m3x2_ck = {
 };
 
 static const struct clksel emu_core_alwon_ck_clksel[] = {
-       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
        { .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -633,7 +633,7 @@ static struct clk dpll4_m2x2_ck = {
 };
 
 static const struct clksel omap_96m_alwon_fck_clksel[] = {
-       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
        { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -659,7 +659,7 @@ static struct clk omap_96m_fck = {
 };
 
 static const struct clksel cm_96m_fck_clksel[] = {
-       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
        { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -701,7 +701,7 @@ static struct clk dpll4_m3x2_ck = {
 };
 
 static const struct clksel virt_omap_54m_fck_clksel[] = {
-       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
        { .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -911,7 +911,7 @@ static struct clk dpll5_m2_ck = {
 };
 
 static const struct clksel omap_120m_fck_clksel[] = {
-       { .parent = &sys_ck,      .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,      .rates = dpll_bypass_rates },
        { .parent = &dpll5_m2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -919,13 +919,13 @@ static const struct clksel omap_120m_fck_clksel[] = {
 static struct clk omap_120m_fck = {
        .name           = "omap_120m_fck",
        .parent         = &dpll5_m2_ck,
-       .init           = &omap2_init_clksel_parent,
-       .clksel_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-       .clksel_mask    = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-       .clksel         = omap_120m_fck_clksel,
+       .init           = &omap2_init_clksel_parent,
+       .clksel_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+       .clksel_mask    = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
+       .clksel         = omap_120m_fck_clksel,
        .flags          = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
-       .recalc         = &omap2_clksel_recalc,
+       .recalc         = &omap2_clksel_recalc,
 };
 
 /* CM EXTERNAL CLOCK OUTPUTS */
@@ -1034,7 +1034,7 @@ static struct clk dpll1_fck = {
  * called 'dpll1_fck'
  */
 static const struct clksel mpu_clksel[] = {
-       { .parent = &dpll1_fck,     .rates = dpll_bypass_rates },
+       { .parent = &dpll1_fck,     .rates = dpll_bypass_rates },
        { .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -1048,6 +1048,7 @@ static struct clk mpu_ck = {
        .clksel         = mpu_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "mpu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1075,6 +1076,8 @@ static struct clk arm_fck = {
        .recalc         = &omap2_clksel_recalc,
 };
 
+/* XXX What about neon_clkdm ? */
+
 /*
  * REVISIT: This clock is never specifically defined in the 3430 TRM,
  * although it is referenced - so this is a guess
@@ -1107,7 +1110,7 @@ static struct clk dpll2_fck = {
  */
 
 static const struct clksel iva2_clksel[] = {
-       { .parent = &dpll2_fck,   .rates = dpll_bypass_rates },
+       { .parent = &dpll2_fck,   .rates = dpll_bypass_rates },
        { .parent = &dpll2_m2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -1123,6 +1126,7 @@ static struct clk iva2_ck = {
        .clksel_mask    = OMAP3430_ST_IVA2_CLK_MASK,
        .clksel         = iva2_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+       .clkdm_name     = "iva2_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1137,6 +1141,7 @@ static struct clk l3_ick = {
        .clksel         = div2_core_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1154,6 +1159,7 @@ static struct clk l4_ick = {
        .clksel         = div2_l3_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &omap2_clksel_recalc,
 
 };
@@ -1183,43 +1189,57 @@ static const struct clksel gfx_l3_clksel[] = {
        { .parent = NULL }
 };
 
-static struct clk gfx_l3_fck = {
-       .name           = "gfx_l3_fck",
+/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
+static struct clk gfx_l3_ck = {
+       .name           = "gfx_l3_ck",
        .parent         = &l3_ick,
        .init           = &omap2_init_clksel_parent,
        .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
        .enable_bit     = OMAP_EN_GFX_SHIFT,
+       .flags          = CLOCK_IN_OMAP3430ES1,
+       .recalc         = &followparent_recalc,
+};
+
+static struct clk gfx_l3_fck = {
+       .name           = "gfx_l3_fck",
+       .parent         = &gfx_l3_ck,
+       .init           = &omap2_init_clksel_parent,
        .clksel_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
        .clksel_mask    = OMAP_CLKSEL_GFX_MASK,
        .clksel         = gfx_l3_clksel,
-       .flags          = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES,
+       .flags          = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES |
+                               PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "gfx_3430es1_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk gfx_l3_ick = {
        .name           = "gfx_l3_ick",
-       .parent         = &l3_ick,
-       .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-       .enable_bit     = OMAP_EN_GFX_SHIFT,
-       .flags          = CLOCK_IN_OMAP3430ES1,
+       .parent         = &gfx_l3_ck,
+       .flags          = CLOCK_IN_OMAP3430ES1 | PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "gfx_3430es1_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk gfx_cg1_ck = {
        .name           = "gfx_cg1_ck",
        .parent         = &gfx_l3_fck, /* REVISIT: correct? */
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430ES1_EN_2D_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES1,
+       .clkdm_name     = "gfx_3430es1_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk gfx_cg2_ck = {
        .name           = "gfx_cg2_ck",
        .parent         = &gfx_l3_fck, /* REVISIT: correct? */
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430ES1_EN_3D_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES1,
+       .clkdm_name     = "gfx_3430es1_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1252,15 +1272,18 @@ static struct clk sgx_fck = {
        .clksel_mask    = OMAP3430ES2_CLKSEL_SGX_MASK,
        .clksel         = sgx_clksel,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "sgx_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk sgx_ick = {
        .name           = "sgx_ick",
        .parent         = &l3_ick,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430ES2_EN_SGX_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "sgx_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1269,9 +1292,11 @@ static struct clk sgx_ick = {
 static struct clk d2d_26m_fck = {
        .name           = "d2d_26m_fck",
        .parent         = &sys_ck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430ES1_EN_D2D_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES1,
+       .clkdm_name     = "d2d_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1291,6 +1316,7 @@ static struct clk gpt10_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT10_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1304,6 +1330,7 @@ static struct clk gpt11_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT11_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1341,6 +1368,7 @@ static struct clk core_96m_fck = {
        .parent         = &omap_96m_fck,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1351,6 +1379,7 @@ static struct clk mmchs3_fck = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430ES2_EN_MMC3_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1361,6 +1390,7 @@ static struct clk mmchs2_fck = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_MMC2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1370,6 +1400,7 @@ static struct clk mspro_fck = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_MSPRO_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1380,6 +1411,7 @@ static struct clk mmchs1_fck = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_MMC1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1390,16 +1422,18 @@ static struct clk i2c3_fck = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_I2C3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk i2c2_fck = {
        .name           = "i2c_fck",
-       .id             = 2,
+       .id             = 2,
        .parent         = &core_96m_fck,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_I2C2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1410,6 +1444,7 @@ static struct clk i2c1_fck = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_I2C1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1443,6 +1478,7 @@ static struct clk mcbsp5_fck = {
        .clksel_mask    = OMAP2_MCBSP5_CLKS_MASK,
        .clksel         = mcbsp_15_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1456,6 +1492,7 @@ static struct clk mcbsp1_fck = {
        .clksel_mask    = OMAP2_MCBSP1_CLKS_MASK,
        .clksel         = mcbsp_15_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1466,6 +1503,7 @@ static struct clk core_48m_fck = {
        .parent         = &omap_48m_fck,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1543,6 +1581,7 @@ static struct clk core_12m_fck = {
        .parent         = &omap_12m_fck,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1581,6 +1620,7 @@ static struct clk ssi_ssr_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_SSI_MASK,
        .clksel         = ssi_ssr_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -1596,11 +1636,17 @@ static struct clk ssi_sst_fck = {
 
 /* CORE_L3_ICK based clocks */
 
+/*
+ * XXX must add clk_enable/clk_disable for these if standard code won't
+ * handle it
+ */
 static struct clk core_l3_ick = {
        .name           = "core_l3_ick",
        .parent         = &l3_ick,
+       .init           = &omap2_init_clk_clkdm,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1610,6 +1656,7 @@ static struct clk hsotgusb_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_HSOTGUSB_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1619,6 +1666,7 @@ static struct clk sdrc_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_SDRC_SHIFT,
        .flags          = CLOCK_IN_OMAP343X | ENABLE_ON_INIT,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1627,6 +1675,7 @@ static struct clk gpmc_fck = {
        .parent         = &core_l3_ick,
        .flags          = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK |
                                ENABLE_ON_INIT,
+       .clkdm_name     = "core_l3_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1654,8 +1703,10 @@ static struct clk pka_ick = {
 static struct clk core_l4_ick = {
        .name           = "core_l4_ick",
        .parent         = &l4_ick,
+       .init           = &omap2_init_clk_clkdm,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1665,6 +1716,7 @@ static struct clk usbtll_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
        .enable_bit     = OMAP3430ES2_EN_USBTLL_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1675,6 +1727,7 @@ static struct clk mmchs3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430ES2_EN_MMC3_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1685,6 +1738,7 @@ static struct clk icr_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_ICR_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1694,6 +1748,7 @@ static struct clk aes2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_AES2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1703,6 +1758,7 @@ static struct clk sha12_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_SHA12_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1712,6 +1768,7 @@ static struct clk des2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_DES2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1722,6 +1779,7 @@ static struct clk mmchs2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MMC2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1732,6 +1790,7 @@ static struct clk mmchs1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MMC1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1741,6 +1800,7 @@ static struct clk mspro_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MSPRO_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1750,6 +1810,7 @@ static struct clk hdq_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_HDQ_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1760,6 +1821,7 @@ static struct clk mcspi4_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MCSPI4_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1770,6 +1832,7 @@ static struct clk mcspi3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MCSPI3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1780,6 +1843,7 @@ static struct clk mcspi2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MCSPI2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1790,6 +1854,7 @@ static struct clk mcspi1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MCSPI1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1800,6 +1865,7 @@ static struct clk i2c3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_I2C3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1810,6 +1876,7 @@ static struct clk i2c2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_I2C2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1820,6 +1887,7 @@ static struct clk i2c1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_I2C1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1829,6 +1897,7 @@ static struct clk uart2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_UART2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1838,6 +1907,7 @@ static struct clk uart1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_UART1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1847,6 +1917,7 @@ static struct clk gpt11_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_GPT11_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1856,6 +1927,7 @@ static struct clk gpt10_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_GPT10_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1866,6 +1938,7 @@ static struct clk mcbsp5_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MCBSP5_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1876,6 +1949,7 @@ static struct clk mcbsp1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MCBSP1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1885,6 +1959,7 @@ static struct clk fac_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430ES1_EN_FAC_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES1,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1894,6 +1969,7 @@ static struct clk mailboxes_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MAILBOXES_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1913,6 +1989,7 @@ static struct clk ssi_l4_ick = {
        .parent         = &l4_ick,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1922,6 +1999,7 @@ static struct clk ssi_ick = {
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_SSI_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -1996,7 +2074,7 @@ static struct clk des1_ick = {
 
 /* DSS */
 static const struct clksel dss1_alwon_fck_clksel[] = {
-       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
        { .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -2011,33 +2089,40 @@ static struct clk dss1_alwon_fck = {
        .clksel_mask    = OMAP3430_ST_PERIPH_CLK_MASK,
        .clksel         = dss1_alwon_fck_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "dss_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk dss_tv_fck = {
        .name           = "dss_tv_fck",
        .parent         = &omap_54m_fck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_TV_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "dss_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk dss_96m_fck = {
        .name           = "dss_96m_fck",
        .parent         = &omap_96m_fck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_TV_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "dss_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk dss2_alwon_fck = {
        .name           = "dss2_alwon_fck",
        .parent         = &sys_ck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_DSS2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "dss_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2045,16 +2130,18 @@ static struct clk dss_ick = {
        /* Handles both L3 and L4 clocks */
        .name           = "dss_ick",
        .parent         = &l4_ick,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "dss_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 /* CAM */
 
 static const struct clksel cam_mclk_clksel[] = {
-       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
+       { .parent = &sys_ck,        .rates = dpll_bypass_rates },
        { .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates },
        { .parent = NULL }
 };
@@ -2069,24 +2156,19 @@ static struct clk cam_mclk = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_CAM_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "cam_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
-static struct clk cam_l3_ick = {
-       .name           = "cam_l3_ick",
-       .parent         = &l3_ick,
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
-       .enable_bit     = OMAP3430_EN_CAM_SHIFT,
-       .flags          = CLOCK_IN_OMAP343X,
-       .recalc         = &followparent_recalc,
-};
-
-static struct clk cam_l4_ick = {
-       .name           = "cam_l4_ick",
+static struct clk cam_ick = {
+       /* Handles both L3 and L4 clocks */
+       .name           = "cam_ick",
        .parent         = &l4_ick,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_CAM_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "cam_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2095,45 +2177,45 @@ static struct clk cam_l4_ick = {
 static struct clk usbhost_120m_fck = {
        .name           = "usbhost_120m_fck",
        .parent         = &omap_120m_fck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430ES2_EN_USBHOST2_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "usbhost_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk usbhost_48m_fck = {
        .name           = "usbhost_48m_fck",
        .parent         = &omap_48m_fck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430ES2_EN_USBHOST1_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "usbhost_clkdm",
        .recalc         = &followparent_recalc,
 };
 
-static struct clk usbhost_l3_ick = {
-       .name           = "usbhost_l3_ick",
-       .parent         = &l3_ick,
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
-       .enable_bit     = OMAP3430ES2_EN_USBHOST_SHIFT,
-       .flags          = CLOCK_IN_OMAP3430ES2,
-       .recalc         = &followparent_recalc,
-};
-
-static struct clk usbhost_l4_ick = {
-       .name           = "usbhost_l4_ick",
+static struct clk usbhost_ick = {
+       /* Handles both L3 and L4 clocks */
+       .name           = "usbhost_ick",
        .parent         = &l4_ick,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430ES2_EN_USBHOST_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "usbhost_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk usbhost_sar_fck = {
        .name           = "usbhost_sar_fck",
        .parent         = &osc_sys_ck,
+       .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL),
        .enable_bit     = OMAP3430ES2_SAVEANDRESTORE_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "usbhost_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2175,6 +2257,7 @@ static struct clk usim_fck = {
        .recalc         = &omap2_clksel_recalc,
 };
 
+/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
 static struct clk gpt1_fck = {
        .name           = "gpt1_fck",
        .init           = &omap2_init_clksel_parent,
@@ -2184,13 +2267,16 @@ static struct clk gpt1_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT1_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk wkup_32k_fck = {
        .name           = "wkup_32k_fck",
+       .init           = &omap2_init_clk_clkdm,
        .parent         = &omap_32k_fck,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2200,6 +2286,7 @@ static struct clk gpio1_fck = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_GPIO1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2209,6 +2296,7 @@ static struct clk wdt2_fck = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_WDT2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2216,6 +2304,7 @@ static struct clk wkup_l4_ick = {
        .name           = "wkup_l4_ick",
        .parent         = &sys_ck,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2227,6 +2316,7 @@ static struct clk usim_ick = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430ES2_EN_USIMOCP_SHIFT,
        .flags          = CLOCK_IN_OMAP3430ES2,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2236,6 +2326,7 @@ static struct clk wdt2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_WDT2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2245,6 +2336,7 @@ static struct clk wdt1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_WDT1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2254,6 +2346,7 @@ static struct clk gpio1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPIO1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2263,15 +2356,18 @@ static struct clk omap_32ksync_ick = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_32KSYNC_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
+/* XXX This clock no longer exists in 3430 TRM rev F */
 static struct clk gpt12_ick = {
        .name           = "gpt12_ick",
        .parent         = &wkup_l4_ick,
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT12_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2281,6 +2377,7 @@ static struct clk gpt1_ick = {
        .enable_reg     = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT1_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "wkup_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2291,16 +2388,20 @@ static struct clk gpt1_ick = {
 static struct clk per_96m_fck = {
        .name           = "per_96m_fck",
        .parent         = &omap_96m_alwon_fck,
+       .init           = &omap2_init_clk_clkdm,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static struct clk per_48m_fck = {
        .name           = "per_48m_fck",
        .parent         = &omap_48m_fck,
+       .init           = &omap2_init_clk_clkdm,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2310,6 +2411,7 @@ static struct clk uart3_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_UART3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2322,6 +2424,7 @@ static struct clk gpt2_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT2_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2334,6 +2437,7 @@ static struct clk gpt3_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT3_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2346,6 +2450,7 @@ static struct clk gpt4_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT4_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2358,6 +2463,7 @@ static struct clk gpt5_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT5_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2370,6 +2476,7 @@ static struct clk gpt6_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT6_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2382,6 +2489,7 @@ static struct clk gpt7_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT7_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2394,6 +2502,7 @@ static struct clk gpt8_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT8_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2406,12 +2515,14 @@ static struct clk gpt9_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_GPT9_MASK,
        .clksel         = omap343x_gpt_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk per_32k_alwon_fck = {
        .name           = "per_32k_alwon_fck",
        .parent         = &omap_32k_fck,
+       .clkdm_name     = "per_clkdm",
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
 };
@@ -2422,6 +2533,7 @@ static struct clk gpio6_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_GPIO6_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2431,6 +2543,7 @@ static struct clk gpio5_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_GPIO5_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2440,6 +2553,7 @@ static struct clk gpio4_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_GPIO4_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2449,6 +2563,7 @@ static struct clk gpio3_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_GPIO3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2458,6 +2573,7 @@ static struct clk gpio2_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_GPIO2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2467,6 +2583,7 @@ static struct clk wdt3_fck = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
        .enable_bit     = OMAP3430_EN_WDT3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2475,6 +2592,7 @@ static struct clk per_l4_ick = {
        .parent         = &l4_ick,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
                                PARENT_CONTROLS_CLOCK,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2484,6 +2602,7 @@ static struct clk gpio6_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPIO6_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2493,6 +2612,7 @@ static struct clk gpio5_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPIO5_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2502,6 +2622,7 @@ static struct clk gpio4_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPIO4_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2511,6 +2632,7 @@ static struct clk gpio3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPIO3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2520,6 +2642,7 @@ static struct clk gpio2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPIO2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2529,6 +2652,7 @@ static struct clk wdt3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_WDT3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2538,6 +2662,7 @@ static struct clk uart3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_UART3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2547,6 +2672,7 @@ static struct clk gpt9_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT9_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2556,6 +2682,7 @@ static struct clk gpt8_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT8_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2565,6 +2692,7 @@ static struct clk gpt7_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT7_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2574,6 +2702,7 @@ static struct clk gpt6_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT6_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2583,6 +2712,7 @@ static struct clk gpt5_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT5_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2592,6 +2722,7 @@ static struct clk gpt4_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT4_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2601,6 +2732,7 @@ static struct clk gpt3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2610,6 +2742,7 @@ static struct clk gpt2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_GPT2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2620,6 +2753,7 @@ static struct clk mcbsp2_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_MCBSP2_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2630,6 +2764,7 @@ static struct clk mcbsp3_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_MCBSP3_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
@@ -2640,12 +2775,13 @@ static struct clk mcbsp4_ick = {
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
        .enable_bit     = OMAP3430_EN_MCBSP4_SHIFT,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 static const struct clksel mcbsp_234_clksel[] = {
        { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates },
-       { .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
+       { .parent = &mcbsp_clks,  .rates = common_mcbsp_mcbsp_rates },
        { .parent = NULL }
 };
 
@@ -2659,6 +2795,7 @@ static struct clk mcbsp2_fck = {
        .clksel_mask    = OMAP2_MCBSP2_CLKS_MASK,
        .clksel         = mcbsp_234_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2672,6 +2809,7 @@ static struct clk mcbsp3_fck = {
        .clksel_mask    = OMAP2_MCBSP3_CLKS_MASK,
        .clksel         = mcbsp_234_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2685,6 +2823,7 @@ static struct clk mcbsp4_fck = {
        .clksel_mask    = OMAP2_MCBSP4_CLKS_MASK,
        .clksel         = mcbsp_234_clksel,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "per_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2732,6 +2871,7 @@ static struct clk emu_src_ck = {
        .clksel_mask    = OMAP3430_MUX_CTRL_MASK,
        .clksel         = emu_src_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "emu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2755,6 +2895,7 @@ static struct clk pclk_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_PCLK_MASK,
        .clksel         = pclk_emu_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "emu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2777,6 +2918,7 @@ static struct clk pclkx2_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_PCLKX2_MASK,
        .clksel         = pclkx2_emu_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "emu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2792,6 +2934,7 @@ static struct clk atclk_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_ATCLK_MASK,
        .clksel         = atclk_emu_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "emu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2802,6 +2945,7 @@ static struct clk traceclk_src_fck = {
        .clksel_mask    = OMAP3430_TRACE_MUX_CTRL_MASK,
        .clksel         = emu_src_clksel,
        .flags          = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+       .clkdm_name     = "emu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2824,6 +2968,7 @@ static struct clk traceclk_fck = {
        .clksel_mask    = OMAP3430_CLKSEL_TRACECLK_MASK,
        .clksel         = traceclk_clksel,
        .flags          = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
+       .clkdm_name     = "emu_clkdm",
        .recalc         = &omap2_clksel_recalc,
 };
 
@@ -2853,11 +2998,13 @@ static struct clk sr_l4_ick = {
        .name           = "sr_l4_ick",
        .parent         = &l4_ick,
        .flags          = CLOCK_IN_OMAP343X,
+       .clkdm_name     = "core_l4_clkdm",
        .recalc         = &followparent_recalc,
 };
 
 /* SECURE_32K_FCK clocks */
 
+/* XXX This clock no longer exists in 3430 TRM rev F */
 static struct clk gpt12_fck = {
        .name           = "gpt12_fck",
        .parent         = &secure_32k_fck,
@@ -2933,6 +3080,7 @@ static struct clk *onchip_34xx_clks[] __initdata = {
        &l3_ick,
        &l4_ick,
        &rm_ick,
+       &gfx_l3_ck,
        &gfx_l3_fck,
        &gfx_l3_ick,
        &gfx_cg1_ck,
@@ -3014,12 +3162,10 @@ static struct clk *onchip_34xx_clks[] __initdata = {
        &dss2_alwon_fck,
        &dss_ick,
        &cam_mclk,
-       &cam_l3_ick,
-       &cam_l4_ick,
+       &cam_ick,
        &usbhost_120m_fck,
        &usbhost_48m_fck,
-       &usbhost_l3_ick,
-       &usbhost_l4_ick,
+       &usbhost_ick,
        &usbhost_sar_fck,
        &usim_fck,
        &gpt1_fck,
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
new file mode 100644 (file)
index 0000000..4c3ce9c
--- /dev/null
@@ -0,0 +1,623 @@
+/*
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley and Jouni Högander
+ *
+ * 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.
+ */
+#ifdef CONFIG_OMAP_DEBUG_CLOCKDOMAIN
+#  define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/limits.h>
+
+#include <linux/io.h>
+
+#include <linux/bitops.h>
+
+#include <mach/clock.h>
+
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "cm.h"
+
+#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
+
+/* clkdm_list contains all registered struct clockdomains */
+static LIST_HEAD(clkdm_list);
+
+/* clkdm_mutex protects clkdm_list add and del ops */
+static DEFINE_MUTEX(clkdm_mutex);
+
+/* array of powerdomain deps to be added/removed when clkdm in hwsup mode */
+static struct clkdm_pwrdm_autodep *autodeps;
+
+
+/* Private functions */
+
+/*
+ * _autodep_lookup - resolve autodep pwrdm names to pwrdm pointers; store
+ * @autodep: struct clkdm_pwrdm_autodep * to resolve
+ *
+ * Resolve autodep powerdomain names to powerdomain pointers via
+ * pwrdm_lookup() and store the pointers in the autodep structure.  An
+ * "autodep" is a powerdomain sleep/wakeup dependency that is
+ * automatically added and removed whenever clocks in the associated
+ * clockdomain are enabled or disabled (respectively) when the
+ * clockdomain is in hardware-supervised mode. Meant to be called
+ * once at clockdomain layer initialization, since these should remain
+ * fixed for a particular architecture.  No return value.
+ */
+static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
+{
+       struct powerdomain *pwrdm;
+
+       if (!autodep)
+               return;
+
+       if (!omap_chip_is(autodep->omap_chip))
+               return;
+
+       pwrdm = pwrdm_lookup(autodep->pwrdm_name);
+       if (!pwrdm) {
+               pr_debug("clockdomain: _autodep_lookup: powerdomain %s "
+                        "does not exist\n", autodep->pwrdm_name);
+               WARN_ON(1);
+               return;
+       }
+       autodep->pwrdm = pwrdm;
+
+       return;
+}
+
+/*
+ * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
+ * @clkdm: struct clockdomain *
+ *
+ * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
+ * in hardware-supervised mode.  Meant to be called from clock framework
+ * when a clock inside clockdomain 'clkdm' is enabled. No return value.
+ */
+static void _clkdm_add_autodeps(struct clockdomain *clkdm)
+{
+       struct clkdm_pwrdm_autodep *autodep;
+
+       for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
+               if (!autodep->pwrdm)
+                       continue;
+
+               pr_debug("clockdomain: adding %s sleepdep/wkdep for "
+                        "pwrdm %s\n", autodep->pwrdm_name,
+                        clkdm->pwrdm->name);
+
+               pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm);
+               pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm);
+       }
+}
+
+/*
+ * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
+ * in hardware-supervised mode.  Meant to be called from clock framework
+ * when a clock inside clockdomain 'clkdm' is disabled.  No return value.
+ */
+static void _clkdm_del_autodeps(struct clockdomain *clkdm)
+{
+       struct clkdm_pwrdm_autodep *autodep;
+
+       for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
+               if (!autodep->pwrdm)
+                       continue;
+
+               pr_debug("clockdomain: removing %s sleepdep/wkdep for "
+                        "pwrdm %s\n", autodep->pwrdm_name,
+                        clkdm->pwrdm->name);
+
+               pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm);
+               pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm);
+       }
+}
+
+
+static struct clockdomain *_clkdm_lookup(const char *name)
+{
+       struct clockdomain *clkdm, *temp_clkdm;
+
+       if (!name)
+               return NULL;
+
+       clkdm = NULL;
+
+       list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+               if (!strcmp(name, temp_clkdm->name)) {
+                       clkdm = temp_clkdm;
+                       break;
+               }
+       }
+
+       return clkdm;
+}
+
+
+/* Public functions */
+
+/**
+ * clkdm_init - set up the clockdomain layer
+ * @clkdms: optional pointer to an array of clockdomains to register
+ * @init_autodeps: optional pointer to an array of autodeps to register
+ *
+ * Set up internal state.  If a pointer to an array of clockdomains
+ * was supplied, loop through the list of clockdomains, register all
+ * that are available on the current platform. Similarly, if a
+ * pointer to an array of clockdomain-powerdomain autodependencies was
+ * provided, register those.  No return value.
+ */
+void clkdm_init(struct clockdomain **clkdms,
+               struct clkdm_pwrdm_autodep *init_autodeps)
+{
+       struct clockdomain **c = NULL;
+       struct clkdm_pwrdm_autodep *autodep = NULL;
+
+       if (clkdms)
+               for (c = clkdms; *c; c++)
+                       clkdm_register(*c);
+
+       autodeps = init_autodeps;
+       if (autodeps)
+               for (autodep = autodeps; autodep->pwrdm_name; autodep++)
+                       _autodep_lookup(autodep);
+}
+
+/**
+ * clkdm_register - register a clockdomain
+ * @clkdm: struct clockdomain * to register
+ *
+ * Adds a clockdomain to the internal clockdomain list.
+ * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+int clkdm_register(struct clockdomain *clkdm)
+{
+       int ret = -EINVAL;
+       struct powerdomain *pwrdm;
+
+       if (!clkdm || !clkdm->name)
+               return -EINVAL;
+
+       if (!omap_chip_is(clkdm->omap_chip))
+               return -EINVAL;
+
+       pwrdm = pwrdm_lookup(clkdm->pwrdm_name);
+       if (!pwrdm) {
+               pr_debug("clockdomain: clkdm_register %s: powerdomain %s "
+                        "does not exist\n", clkdm->name, clkdm->pwrdm_name);
+               return -EINVAL;
+       }
+       clkdm->pwrdm = pwrdm;
+
+       mutex_lock(&clkdm_mutex);
+       /* Verify that the clockdomain is not already registered */
+       if (_clkdm_lookup(clkdm->name)) {
+               ret = -EEXIST;
+               goto cr_unlock;
+       };
+
+       list_add(&clkdm->node, &clkdm_list);
+
+       pwrdm_add_clkdm(pwrdm, clkdm);
+
+       pr_debug("clockdomain: registered %s\n", clkdm->name);
+       ret = 0;
+
+cr_unlock:
+       mutex_unlock(&clkdm_mutex);
+
+       return ret;
+}
+
+/**
+ * clkdm_unregister - unregister a clockdomain
+ * @clkdm: struct clockdomain * to unregister
+ *
+ * Removes a clockdomain from the internal clockdomain list.  Returns
+ * -EINVAL if clkdm argument is NULL.
+ */
+int clkdm_unregister(struct clockdomain *clkdm)
+{
+       if (!clkdm)
+               return -EINVAL;
+
+       pwrdm_del_clkdm(clkdm->pwrdm, clkdm);
+
+       mutex_lock(&clkdm_mutex);
+       list_del(&clkdm->node);
+       mutex_unlock(&clkdm_mutex);
+
+       pr_debug("clockdomain: unregistered %s\n", clkdm->name);
+
+       return 0;
+}
+
+/**
+ * clkdm_lookup - look up a clockdomain by name, return a pointer
+ * @name: name of clockdomain
+ *
+ * Find a registered clockdomain by its name.  Returns a pointer to the
+ * struct clockdomain if found, or NULL otherwise.
+ */
+struct clockdomain *clkdm_lookup(const char *name)
+{
+       struct clockdomain *clkdm, *temp_clkdm;
+
+       if (!name)
+               return NULL;
+
+       clkdm = NULL;
+
+       mutex_lock(&clkdm_mutex);
+       list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+               if (!strcmp(name, temp_clkdm->name)) {
+                       clkdm = temp_clkdm;
+                       break;
+               }
+       }
+       mutex_unlock(&clkdm_mutex);
+
+       return clkdm;
+}
+
+/**
+ * clkdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * Call the supplied function for each registered clockdomain.
+ * The callback function can return anything but 0 to bail
+ * out early from the iterator.  The callback function is called with
+ * the clkdm_mutex held, so no clockdomain structure manipulation
+ * functions should be called from the callback, although hardware
+ * clockdomain control functions are fine.  Returns the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure; or -EINVAL if the function pointer
+ * is null.
+ */
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm))
+{
+       struct clockdomain *clkdm;
+       int ret = 0;
+
+       if (!fn)
+               return -EINVAL;
+
+       mutex_lock(&clkdm_mutex);
+       list_for_each_entry(clkdm, &clkdm_list, node) {
+               ret = (*fn)(clkdm);
+               if (ret)
+                       break;
+       }
+       mutex_unlock(&clkdm_mutex);
+
+       return ret;
+}
+
+
+/**
+ * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in
+ * @clkdm: struct clockdomain *
+ *
+ * Return a pointer to the struct powerdomain that the specified clockdomain
+ * 'clkdm' exists in, or returns NULL if clkdm argument is NULL.
+ */
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
+{
+       if (!clkdm)
+               return NULL;
+
+       return clkdm->pwrdm;
+}
+
+
+/* Hardware clockdomain control */
+
+/**
+ * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode
+ * @clk: struct clk * of a clockdomain
+ *
+ * Return the clockdomain's current state transition mode from the
+ * corresponding domain CM_CLKSTCTRL register. Returns -EINVAL if clk
+ * is NULL or the current mode upon success.
+ */
+static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)
+{
+       u32 v;
+
+       if (!clkdm)
+               return -EINVAL;
+
+       v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+       v &= clkdm->clktrctrl_mask;
+       v >>= __ffs(clkdm->clktrctrl_mask);
+
+       return v;
+}
+
+/**
+ * omap2_clkdm_sleep - force clockdomain sleep transition
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a sleep transition on the specified
+ * clockdomain 'clkdm'.  Returns -EINVAL if clk is NULL or if
+ * clockdomain does not support software-initiated sleep; 0 upon
+ * success.
+ */
+int omap2_clkdm_sleep(struct clockdomain *clkdm)
+{
+       if (!clkdm)
+               return -EINVAL;
+
+       if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+               pr_debug("clockdomain: %s does not support forcing "
+                        "sleep via software\n", clkdm->name);
+               return -EINVAL;
+       }
+
+       pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
+
+       if (cpu_is_omap24xx()) {
+
+               cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
+                                   clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       } else if (cpu_is_omap34xx()) {
+
+               u32 v = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
+                        __ffs(clkdm->clktrctrl_mask));
+
+               cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
+                                   clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+
+       } else {
+               BUG();
+       };
+
+       return 0;
+}
+
+/**
+ * omap2_clkdm_wakeup - force clockdomain wakeup transition
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a wakeup transition on the specified
+ * clockdomain 'clkdm'.  Returns -EINVAL if clkdm is NULL or if the
+ * clockdomain does not support software-controlled wakeup; 0 upon
+ * success.
+ */
+int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+{
+       if (!clkdm)
+               return -EINVAL;
+
+       if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+               pr_debug("clockdomain: %s does not support forcing "
+                        "wakeup via software\n", clkdm->name);
+               return -EINVAL;
+       }
+
+       pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
+
+       if (cpu_is_omap24xx()) {
+
+               cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
+                                     clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       } else if (cpu_is_omap34xx()) {
+
+               u32 v = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
+                        __ffs(clkdm->clktrctrl_mask));
+
+               cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
+                                   clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+
+       } else {
+               BUG();
+       };
+
+       return 0;
+}
+
+/**
+ * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Allow the hardware to automatically switch the clockdomain into
+ * active or idle states, as needed by downstream clocks.  If the
+ * clockdomain has any downstream clocks enabled in the clock
+ * framework, wkdep/sleepdep autodependencies are added; this is so
+ * device drivers can read and write to the device.  No return value.
+ */
+void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+       u32 v;
+
+       if (!clkdm)
+               return;
+
+       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
+               pr_debug("clock: automatic idle transitions cannot be enabled "
+                        "on clockdomain %s\n", clkdm->name);
+               return;
+       }
+
+       pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
+                clkdm->name);
+
+       if (atomic_read(&clkdm->usecount) > 0)
+               _clkdm_add_autodeps(clkdm);
+
+       if (cpu_is_omap24xx())
+               v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
+       else if (cpu_is_omap34xx())
+               v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
+       else
+               BUG();
+
+
+       cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
+                           v << __ffs(clkdm->clktrctrl_mask),
+                           clkdm->pwrdm->prcm_offs,
+                           CM_CLKSTCTRL);
+}
+
+/**
+ * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Prevent the hardware from automatically switching the clockdomain
+ * into inactive or idle states.  If the clockdomain has downstream
+ * clocks enabled in the clock framework, wkdep/sleepdep
+ * autodependencies are removed.  No return value.
+ */
+void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+       u32 v;
+
+       if (!clkdm)
+               return;
+
+       if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) {
+               pr_debug("clockdomain: automatic idle transitions cannot be "
+                        "disabled on %s\n", clkdm->name);
+               return;
+       }
+
+       pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
+                clkdm->name);
+
+       if (cpu_is_omap24xx())
+               v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
+       else if (cpu_is_omap34xx())
+               v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
+       else
+               BUG();
+
+       cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
+                           v << __ffs(clkdm->clktrctrl_mask),
+                           clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+
+       if (atomic_read(&clkdm->usecount) > 0)
+               _clkdm_del_autodeps(clkdm);
+}
+
+
+/* Clockdomain-to-clock framework interface code */
+
+/**
+ * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the enabled downstream clock
+ *
+ * Increment the usecount of this clockdomain 'clkdm' and ensure that
+ * it is awake.  Intended to be called by clk_enable() code.  If the
+ * clockdomain is in software-supervised idle mode, force the
+ * clockdomain to wake.  If the clockdomain is in hardware-supervised
+ * idle mode, add clkdm-pwrdm autodependencies, to ensure that devices
+ * in the clockdomain can be read from/written to by on-chip processors.
+ * Returns -EINVAL if passed null pointers; returns 0 upon success or
+ * if the clockdomain is in hwsup idle mode.
+ */
+int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
+{
+       int v;
+
+       /*
+        * XXX Rewrite this code to maintain a list of enabled
+        * downstream clocks for debugging purposes?
+        */
+
+       if (!clkdm || !clk)
+               return -EINVAL;
+
+       if (atomic_inc_return(&clkdm->usecount) > 1)
+               return 0;
+
+       /* Clockdomain now has one enabled downstream clock */
+
+       pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
+                clk->name);
+
+       v = omap2_clkdm_clktrctrl_read(clkdm);
+
+       if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
+           (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+               _clkdm_add_autodeps(clkdm);
+       else
+               omap2_clkdm_wakeup(clkdm);
+
+       return 0;
+}
+
+/**
+ * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the disabled downstream clock
+ *
+ * Decrement the usecount of this clockdomain 'clkdm'. Intended to be
+ * called by clk_disable() code.  If the usecount goes to 0, put the
+ * clockdomain to sleep (software-supervised mode) or remove the
+ * clkdm-pwrdm autodependencies (hardware-supervised mode).  Returns
+ * -EINVAL if passed null pointers; -ERANGE if the clkdm usecount
+ * underflows and debugging is enabled; or returns 0 upon success or
+ * if the clockdomain is in hwsup idle mode.
+ */
+int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
+{
+       int v;
+
+       /*
+        * XXX Rewrite this code to maintain a list of enabled
+        * downstream clocks for debugging purposes?
+        */
+
+       if (!clkdm || !clk)
+               return -EINVAL;
+
+#ifdef DEBUG
+       if (atomic_read(&clkdm->usecount) == 0) {
+               WARN_ON(1); /* underflow */
+               return -ERANGE;
+       }
+#endif
+
+       if (atomic_dec_return(&clkdm->usecount) > 0)
+               return 0;
+
+       /* All downstream clocks of this clockdomain are now disabled */
+
+       pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
+                clk->name);
+
+       v = omap2_clkdm_clktrctrl_read(clkdm);
+
+       if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
+           (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+               _clkdm_del_autodeps(clkdm);
+       else
+               omap2_clkdm_sleep(clkdm);
+
+       return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
new file mode 100644 (file)
index 0000000..cd86dcc
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * OMAP2/3 clockdomains
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
+
+#include <mach/clockdomain.h>
+
+/*
+ * OMAP2/3-common clockdomains
+ */
+
+/* This is an implicit clockdomain - it is never defined as such in TRM */
+static struct clockdomain wkup_clkdm = {
+       .name           = "wkup_clkdm",
+       .pwrdm_name     = "wkup_pwrdm",
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+/*
+ * 2420-only clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP2420)
+
+static struct clockdomain mpu_2420_clkdm = {
+       .name           = "mpu_clkdm",
+       .pwrdm_name     = "mpu_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain iva1_2420_clkdm = {
+       .name           = "iva1_clkdm",
+       .pwrdm_name     = "dsp_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+#endif  /* CONFIG_ARCH_OMAP2420 */
+
+
+/*
+ * 2430-only clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP2430)
+
+static struct clockdomain mpu_2430_clkdm = {
+       .name           = "mpu_clkdm",
+       .pwrdm_name     = "mpu_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static struct clockdomain mdm_clkdm = {
+       .name           = "mdm_clkdm",
+       .pwrdm_name     = "mdm_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+#endif    /* CONFIG_ARCH_OMAP2430 */
+
+
+/*
+ * 24XX-only clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP24XX)
+
+static struct clockdomain dsp_clkdm = {
+       .name           = "dsp_clkdm",
+       .pwrdm_name     = "dsp_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain gfx_24xx_clkdm = {
+       .name           = "gfx_clkdm",
+       .pwrdm_name     = "gfx_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain core_l3_24xx_clkdm = {
+       .name           = "core_l3_clkdm",
+       .pwrdm_name     = "core_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain core_l4_24xx_clkdm = {
+       .name           = "core_l4_clkdm",
+       .pwrdm_name     = "core_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain dss_24xx_clkdm = {
+       .name           = "dss_clkdm",
+       .pwrdm_name     = "core_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+#endif   /* CONFIG_ARCH_OMAP24XX */
+
+
+/*
+ * 34xx clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+
+static struct clockdomain mpu_34xx_clkdm = {
+       .name           = "mpu_clkdm",
+       .pwrdm_name     = "mpu_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain neon_clkdm = {
+       .name           = "neon_clkdm",
+       .pwrdm_name     = "neon_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain iva2_clkdm = {
+       .name           = "iva2_clkdm",
+       .pwrdm_name     = "iva2_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain gfx_3430es1_clkdm = {
+       .name           = "gfx_clkdm",
+       .pwrdm_name     = "gfx_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
+};
+
+static struct clockdomain sgx_clkdm = {
+       .name           = "sgx_clkdm",
+       .pwrdm_name     = "sgx_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+};
+
+/*
+ * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
+ * then that information was removed from the 34xx ES2+ TRM.  It is
+ * unclear whether the core is still there, but the clockdomain logic
+ * is there, and must be programmed to an appropriate state if the
+ * CORE clockdomain is to become inactive.
+ */
+static struct clockdomain d2d_clkdm = {
+       .name           = "d2d_clkdm",
+       .pwrdm_name     = "core_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain core_l3_34xx_clkdm = {
+       .name           = "core_l3_clkdm",
+       .pwrdm_name     = "core_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain core_l4_34xx_clkdm = {
+       .name           = "core_l4_clkdm",
+       .pwrdm_name     = "core_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dss_34xx_clkdm = {
+       .name           = "dss_clkdm",
+       .pwrdm_name     = "dss_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain cam_clkdm = {
+       .name           = "cam_clkdm",
+       .pwrdm_name     = "cam_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain usbhost_clkdm = {
+       .name           = "usbhost_clkdm",
+       .pwrdm_name     = "usbhost_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+};
+
+static struct clockdomain per_clkdm = {
+       .name           = "per_clkdm",
+       .pwrdm_name     = "per_pwrdm",
+       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain emu_clkdm = {
+       .name           = "emu_clkdm",
+       .pwrdm_name     = "emu_pwrdm",
+       .flags          = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP,
+       .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+#endif   /* CONFIG_ARCH_OMAP34XX */
+
+/*
+ * Clockdomain-powerdomain hwsup dependencies (34XX only)
+ */
+
+static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "iva2_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL }
+};
+
+/*
+ *
+ */
+
+static struct clockdomain *clockdomains_omap[] = {
+
+       &wkup_clkdm,
+
+#ifdef CONFIG_ARCH_OMAP2420
+       &mpu_2420_clkdm,
+       &iva1_2420_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+       &mpu_2430_clkdm,
+       &mdm_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP24XX
+       &dsp_clkdm,
+       &gfx_24xx_clkdm,
+       &core_l3_24xx_clkdm,
+       &core_l4_24xx_clkdm,
+       &dss_24xx_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+       &mpu_34xx_clkdm,
+       &neon_clkdm,
+       &iva2_clkdm,
+       &gfx_3430es1_clkdm,
+       &sgx_clkdm,
+       &d2d_clkdm,
+       &core_l3_34xx_clkdm,
+       &core_l4_34xx_clkdm,
+       &dss_34xx_clkdm,
+       &cam_clkdm,
+       &usbhost_clkdm,
+       &per_clkdm,
+       &emu_clkdm,
+#endif
+
+       NULL,
+};
+
+#endif
index 20ac38100678a1eb2c82d5b7e76aaddd7bb9be2b..1098ecfab861e2b42a0a6130fbe0b2d55ceb0004 100644 (file)
@@ -63,7 +63,8 @@
 #define OMAP24XX_CLKSEL_MPU_MASK                       (0x1f << 0)
 
 /* CM_CLKSTCTRL_MPU */
-#define OMAP24XX_AUTOSTATE_MPU                         (1 << 0)
+#define OMAP24XX_AUTOSTATE_MPU_SHIFT                   0
+#define OMAP24XX_AUTOSTATE_MPU_MASK                    (1 << 0)
 
 /* CM_FCLKEN1_CORE specific bits*/
 #define OMAP24XX_EN_TV_SHIFT                           2
 #define OMAP24XX_CLKSEL_GPT2_MASK                      (0x3 << 2)
 
 /* CM_CLKSTCTRL_CORE */
-#define OMAP24XX_AUTOSTATE_DSS                         (1 << 2)
-#define OMAP24XX_AUTOSTATE_L4                          (1 << 1)
-#define OMAP24XX_AUTOSTATE_L3                          (1 << 0)
+#define OMAP24XX_AUTOSTATE_DSS_SHIFT                   2
+#define OMAP24XX_AUTOSTATE_DSS_MASK                    (1 << 2)
+#define OMAP24XX_AUTOSTATE_L4_SHIFT                    1
+#define OMAP24XX_AUTOSTATE_L4_MASK                     (1 << 1)
+#define OMAP24XX_AUTOSTATE_L3_SHIFT                    0
+#define OMAP24XX_AUTOSTATE_L3_MASK                     (1 << 0)
 
 /* CM_FCLKEN_GFX */
 #define OMAP24XX_EN_3D_SHIFT                           2
 /* CM_CLKSEL_GFX specific bits */
 
 /* CM_CLKSTCTRL_GFX */
-#define OMAP24XX_AUTOSTATE_GFX                         (1 << 0)
+#define OMAP24XX_AUTOSTATE_GFX_SHIFT                   0
+#define OMAP24XX_AUTOSTATE_GFX_MASK                    (1 << 0)
 
 /* CM_FCLKEN_WKUP specific bits */
 
 #define OMAP24XX_CLKSEL_DSP_MASK                       (0x1f << 0)
 
 /* CM_CLKSTCTRL_DSP */
-#define OMAP2420_AUTOSTATE_IVA                         (1 << 8)
-#define OMAP24XX_AUTOSTATE_DSP                         (1 << 0)
+#define OMAP2420_AUTOSTATE_IVA_SHIFT                   8
+#define OMAP2420_AUTOSTATE_IVA_MASK                    (1 << 8)
+#define OMAP24XX_AUTOSTATE_DSP_SHIFT                   0
+#define OMAP24XX_AUTOSTATE_DSP_MASK                    (1 << 0)
 
 /* CM_FCLKEN_MDM */
 /* 2430 only */
 
 /* CM_CLKSTCTRL_MDM */
 /* 2430 only */
-#define OMAP2430_AUTOSTATE_MDM                         (1 << 0)
+#define OMAP2430_AUTOSTATE_MDM_SHIFT                   0
+#define OMAP2430_AUTOSTATE_MDM_MASK                    (1 << 0)
 
 #endif
index ee4c0ca1a7087af06ad8bb45498accbeb67f2cea..219f5c8d9659413146dc3f72c257280cd33e67e6 100644 (file)
@@ -96,7 +96,8 @@
 #define OMAP3430_CLKTRCTRL_IVA2_MASK                   (0x3 << 0)
 
 /* CM_CLKSTST_IVA2 */
-#define OMAP3430_CLKACTIVITY_IVA2                      (1 << 0)
+#define OMAP3430_CLKACTIVITY_IVA2_SHIFT                        0
+#define OMAP3430_CLKACTIVITY_IVA2_MASK                 (1 << 0)
 
 /* CM_REVISION specific bits */
 
 #define OMAP3430_CLKTRCTRL_MPU_MASK                    (0x3 << 0)
 
 /* CM_CLKSTST_MPU */
-#define OMAP3430_CLKACTIVITY_MPU                       (1 << 0)
+#define OMAP3430_CLKACTIVITY_MPU_SHIFT                 0
+#define OMAP3430_CLKACTIVITY_MPU_MASK                  (1 << 0)
 
 /* CM_FCLKEN1_CORE specific bits */
 
 #define OMAP3430_CLKTRCTRL_L3_MASK                     (0x3 << 0)
 
 /* CM_CLKSTST_CORE */
-#define OMAP3430ES1_CLKACTIVITY_D2D                    (1 << 2)
-#define OMAP3430_CLKACTIVITY_L4                                (1 << 1)
-#define OMAP3430_CLKACTIVITY_L3                                (1 << 0)
+#define OMAP3430ES1_CLKACTIVITY_D2D_SHIFT              2
+#define OMAP3430ES1_CLKACTIVITY_D2D_MASK               (1 << 2)
+#define OMAP3430_CLKACTIVITY_L4_SHIFT                  1
+#define OMAP3430_CLKACTIVITY_L4_MASK                   (1 << 1)
+#define OMAP3430_CLKACTIVITY_L3_SHIFT                  0
+#define OMAP3430_CLKACTIVITY_L3_MASK                   (1 << 0)
 
 /* CM_FCLKEN_GFX */
 #define OMAP3430ES1_EN_3D                              (1 << 2)
 #define OMAP3430ES1_CLKTRCTRL_GFX_MASK                 (0x3 << 0)
 
 /* CM_CLKSTST_GFX */
-#define OMAP3430ES1_CLKACTIVITY_GFX                    (1 << 0)
+#define OMAP3430ES1_CLKACTIVITY_GFX_SHIFT              0
+#define OMAP3430ES1_CLKACTIVITY_GFX_MASK               (1 << 0)
 
 /* CM_FCLKEN_SGX */
 #define OMAP3430ES2_EN_SGX_SHIFT                       1
 #define OMAP3430ES2_CLKSEL_SGX_SHIFT                   0
 #define OMAP3430ES2_CLKSEL_SGX_MASK                    (0x7 << 0)
 
+/* CM_CLKSTCTRL_SGX */
+#define OMAP3430ES2_CLKTRCTRL_SGX_SHIFT                        0
+#define OMAP3430ES2_CLKTRCTRL_SGX_MASK                 (0x3 << 0)
+
+/* CM_CLKSTST_SGX */
+#define OMAP3430ES2_CLKACTIVITY_SGX_SHIFT              0
+#define OMAP3430ES2_CLKACTIVITY_SGX_MASK               (1 << 0)
+
 /* CM_FCLKEN_WKUP specific bits */
 #define OMAP3430ES2_EN_USIMOCP_SHIFT                   9
 
 #define OMAP3430_CLKTRCTRL_DSS_MASK                    (0x3 << 0)
 
 /* CM_CLKSTST_DSS */
-#define OMAP3430_CLKACTIVITY_DSS                       (1 << 0)
+#define OMAP3430_CLKACTIVITY_DSS_SHIFT                 0
+#define OMAP3430_CLKACTIVITY_DSS_MASK                  (1 << 0)
 
 /* CM_FCLKEN_CAM specific bits */
 
 #define OMAP3430_CLKTRCTRL_CAM_MASK                    (0x3 << 0)
 
 /* CM_CLKSTST_CAM */
-#define OMAP3430_CLKACTIVITY_CAM                       (1 << 0)
+#define OMAP3430_CLKACTIVITY_CAM_SHIFT                 0
+#define OMAP3430_CLKACTIVITY_CAM_MASK                  (1 << 0)
 
 /* CM_FCLKEN_PER specific bits */
 
 #define OMAP3430_CLKTRCTRL_PER_MASK                    (0x3 << 0)
 
 /* CM_CLKSTST_PER */
-#define OMAP3430_CLKACTIVITY_PER                       (1 << 0)
+#define OMAP3430_CLKACTIVITY_PER_SHIFT                 0
+#define OMAP3430_CLKACTIVITY_PER_MASK                  (1 << 0)
 
 /* CM_CLKSEL1_EMU */
 #define OMAP3430_DIV_DPLL4_SHIFT                       24
 #define OMAP3430_CLKTRCTRL_EMU_MASK                    (0x3 << 0)
 
 /* CM_CLKSTST_EMU */
-#define OMAP3430_CLKACTIVITY_EMU                       (1 << 0)
+#define OMAP3430_CLKACTIVITY_EMU_SHIFT                 0
+#define OMAP3430_CLKACTIVITY_EMU_MASK                  (1 << 0)
 
 /* CM_CLKSEL2_EMU specific bits */
 #define OMAP3430_CORE_DPLL_EMU_MULT_SHIFT              8
 #define OMAP3430ES2_CLKTRCTRL_USBHOST_SHIFT            0
 #define OMAP3430ES2_CLKTRCTRL_USBHOST_MASK             (3 << 0)
 
-
+/* CM_CLKSTST_USBHOST */
+#define OMAP3430ES2_CLKACTIVITY_USBHOST_SHIFT          0
+#define OMAP3430ES2_CLKACTIVITY_USBHOST_MASK           (1 << 0)
 
 #endif
index 87a44c715aa4dd1b0604f4f81874c15df9de5d7b..65fdf78c91e1b1d03c62f006d0937e35b16f3d28 100644 (file)
@@ -18,7 +18,7 @@
 
 #ifndef __ASSEMBLER__
 #define OMAP_CM_REGADDR(module, reg)                                   \
-       (void __iomem *)IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg))
+                       IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg))
 #else
 #define OMAP2420_CM_REGADDR(module, reg)                               \
                        IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
index 2ee954a0bc7c23733fc186b27ece2dc8e755e64d..90af2ac469aaccc74401ceea7fe5487e63a7dd6b 100644 (file)
 #include <mach/board.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
-
-#if    defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
-
-#define OMAP2_I2C_BASE2                0x48072000
-#define OMAP2_I2C_INT2         57
-
-static struct resource i2c_resources2[] = {
-       {
-               .start          = OMAP2_I2C_BASE2,
-               .end            = OMAP2_I2C_BASE2 + 0x3f,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = OMAP2_I2C_INT2,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device omap_i2c_device2 = {
-       .name           = "i2c_omap",
-       .id             = 2,
-       .num_resources  = ARRAY_SIZE(i2c_resources2),
-       .resource       = i2c_resources2,
-};
-
-/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */
-static void omap_init_i2c(void)
-{
-       /* REVISIT: Second I2C not in use on H4? */
-       if (machine_is_omap_h4())
-               return;
-
-       if (!cpu_is_omap2430()) {
-               omap_cfg_reg(J15_24XX_I2C2_SCL);
-               omap_cfg_reg(H19_24XX_I2C2_SDA);
-       }
-       (void) platform_device_register(&omap_i2c_device2);
-}
-
-#else
-
-static void omap_init_i2c(void) {}
-
-#endif
+#include <mach/eac.h>
 
 #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
 #define OMAP2_MBOX_BASE                IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
@@ -104,7 +61,9 @@ static inline void omap_init_mbox(void) { }
 
 #if defined(CONFIG_OMAP_STI)
 
-#define OMAP2_STI_BASE         IO_ADDRESS(0x48068000)
+#if defined(CONFIG_ARCH_OMAP2)
+
+#define OMAP2_STI_BASE         0x48068000
 #define OMAP2_STI_CHANNEL_BASE 0x54000000
 #define OMAP2_STI_IRQ          4
 
@@ -124,6 +83,25 @@ static struct resource sti_resources[] = {
                .flags          = IORESOURCE_IRQ,
        }
 };
+#elif defined(CONFIG_ARCH_OMAP3)
+
+#define OMAP3_SDTI_BASE                0x54500000
+#define OMAP3_SDTI_CHANNEL_BASE        0x54600000
+
+static struct resource sti_resources[] = {
+       {
+               .start          = OMAP3_SDTI_BASE,
+               .end            = OMAP3_SDTI_BASE + 0xFFF,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = OMAP3_SDTI_CHANNEL_BASE,
+               .end            = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1,
+               .flags          = IORESOURCE_MEM,
+       }
+};
+
+#endif
 
 static struct platform_device sti_device = {
        .name           = "sti",
@@ -140,12 +118,14 @@ static inline void omap_init_sti(void)
 static inline void omap_init_sti(void) {}
 #endif
 
-#if defined(CONFIG_SPI_OMAP24XX)
+#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
 
 #include <mach/mcspi.h>
 
 #define OMAP2_MCSPI1_BASE              0x48098000
 #define OMAP2_MCSPI2_BASE              0x4809a000
+#define OMAP2_MCSPI3_BASE              0x480b8000
+#define OMAP2_MCSPI4_BASE              0x480ba000
 
 static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
        .num_cs         = 4,
@@ -159,7 +139,7 @@ static struct resource omap2_mcspi1_resources[] = {
        },
 };
 
-struct platform_device omap2_mcspi1 = {
+static struct platform_device omap2_mcspi1 = {
        .name           = "omap2_mcspi",
        .id             = 1,
        .num_resources  = ARRAY_SIZE(omap2_mcspi1_resources),
@@ -181,7 +161,7 @@ static struct resource omap2_mcspi2_resources[] = {
        },
 };
 
-struct platform_device omap2_mcspi2 = {
+static struct platform_device omap2_mcspi2 = {
        .name           = "omap2_mcspi",
        .id             = 2,
        .num_resources  = ARRAY_SIZE(omap2_mcspi2_resources),
@@ -191,16 +171,162 @@ struct platform_device omap2_mcspi2 = {
        },
 };
 
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
+static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
+       .num_cs         = 2,
+};
+
+static struct resource omap2_mcspi3_resources[] = {
+       {
+       .start          = OMAP2_MCSPI3_BASE,
+       .end            = OMAP2_MCSPI3_BASE + 0xff,
+       .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device omap2_mcspi3 = {
+       .name           = "omap2_mcspi",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(omap2_mcspi3_resources),
+       .resource       = omap2_mcspi3_resources,
+       .dev            = {
+               .platform_data = &omap2_mcspi3_config,
+       },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
+       .num_cs         = 1,
+};
+
+static struct resource omap2_mcspi4_resources[] = {
+       {
+               .start          = OMAP2_MCSPI4_BASE,
+               .end            = OMAP2_MCSPI4_BASE + 0xff,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device omap2_mcspi4 = {
+       .name           = "omap2_mcspi",
+       .id             = 4,
+       .num_resources  = ARRAY_SIZE(omap2_mcspi4_resources),
+       .resource       = omap2_mcspi4_resources,
+       .dev            = {
+               .platform_data = &omap2_mcspi4_config,
+       },
+};
+#endif
+
 static void omap_init_mcspi(void)
 {
        platform_device_register(&omap2_mcspi1);
        platform_device_register(&omap2_mcspi2);
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
+       platform_device_register(&omap2_mcspi3);
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+       platform_device_register(&omap2_mcspi4);
+#endif
 }
 
 #else
 static inline void omap_init_mcspi(void) {}
 #endif
 
+#ifdef CONFIG_SND_OMAP24XX_EAC
+
+#define OMAP2_EAC_BASE                 0x48090000
+
+static struct resource omap2_eac_resources[] = {
+       {
+               .start          = OMAP2_EAC_BASE,
+               .end            = OMAP2_EAC_BASE + 0x109,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device omap2_eac_device = {
+       .name           = "omap24xx-eac",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(omap2_eac_resources),
+       .resource       = omap2_eac_resources,
+       .dev = {
+               .platform_data = NULL,
+       },
+};
+
+void omap_init_eac(struct eac_platform_data *pdata)
+{
+       omap2_eac_device.dev.platform_data = pdata;
+       platform_device_register(&omap2_eac_device);
+}
+
+#else
+void omap_init_eac(struct eac_platform_data *pdata) {}
+#endif
+
+#ifdef CONFIG_OMAP_SHA1_MD5
+static struct resource sha1_md5_resources[] = {
+       {
+               .start  = OMAP24XX_SEC_SHA1MD5_BASE,
+               .end    = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_24XX_SHA1MD5,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device sha1_md5_device = {
+       .name           = "OMAP SHA1/MD5",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(sha1_md5_resources),
+       .resource       = sha1_md5_resources,
+};
+
+static void omap_init_sha1_md5(void)
+{
+       platform_device_register(&sha1_md5_device);
+}
+#else
+static inline void omap_init_sha1_md5(void) { }
+#endif
+
+#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
+#define OMAP_HDQ_BASE  0x480B2000
+#endif
+static struct resource omap_hdq_resources[] = {
+       {
+               .start          = OMAP_HDQ_BASE,
+               .end            = OMAP_HDQ_BASE + 0x1C,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_24XX_HDQ_IRQ,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+static struct platform_device omap_hdq_dev = {
+       .name = "omap_hdq",
+       .id = 0,
+       .dev = {
+               .platform_data = NULL,
+       },
+       .num_resources  = ARRAY_SIZE(omap_hdq_resources),
+       .resource       = omap_hdq_resources,
+};
+static inline void omap_hdq_init(void)
+{
+       (void) platform_device_register(&omap_hdq_dev);
+}
+#else
+static inline void omap_hdq_init(void) {}
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 static int __init omap2_init_devices(void)
@@ -208,10 +334,11 @@ static int __init omap2_init_devices(void)
        /* please keep these calls, and their implementations above,
         * in alphabetical order so they're easier to sort through.
         */
-       omap_init_i2c();
        omap_init_mbox();
        omap_init_mcspi();
+       omap_hdq_init();
        omap_init_sti();
+       omap_init_sha1_md5();
 
        return 0;
 }
index af1081a0b27c9549b0dedecaac107991afb553b2..763bdbeaf68182c87389d36a3ed4a53db09e59ed 100644 (file)
@@ -9,6 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#undef DEBUG
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <asm/mach-types.h>
 #include <mach/gpmc.h>
 
-#undef DEBUG
-
-#ifdef CONFIG_ARCH_OMAP2420
-#define GPMC_BASE              0x6800a000
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2430
-#define GPMC_BASE              0x6E000000
-#endif
+#include <mach/sdrc.h>
 
+/* GPMC register offsets */
 #define GPMC_REVISION          0x00
 #define GPMC_SYSCONFIG         0x10
 #define GPMC_SYSSTATUS         0x14
@@ -51,7 +47,6 @@
 #define GPMC_CS0               0x60
 #define GPMC_CS_SIZE           0x30
 
-#define GPMC_CS_NUM            8
 #define GPMC_MEM_START         0x00000000
 #define GPMC_MEM_END           0x3FFFFFFF
 #define BOOT_ROM_SPACE         0x100000        /* 1MB */
@@ -64,12 +59,9 @@ static struct resource       gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned                gpmc_cs_map;
 
-static void __iomem *gpmc_base =
-       (void __iomem *) IO_ADDRESS(GPMC_BASE);
-static void __iomem *gpmc_cs_base =
-       (void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0;
+static void __iomem *gpmc_base;
 
-static struct clk *gpmc_fck;
+static struct clk *gpmc_l3_clk;
 
 static void gpmc_write_reg(int idx, u32 val)
 {
@@ -85,19 +77,32 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val)
 {
        void __iomem *reg_addr;
 
-       reg_addr = gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx;
+       reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx;
        __raw_writel(val, reg_addr);
 }
 
 u32 gpmc_cs_read_reg(int cs, int idx)
 {
-       return __raw_readl(gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx);
+       void __iomem *reg_addr;
+
+       reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx;
+       return __raw_readl(reg_addr);
 }
 
+/* TODO: Add support for gpmc_fck to clock framework and use it */
 unsigned long gpmc_get_fclk_period(void)
 {
-       /* In picoseconds */
-       return 1000000000 / ((clk_get_rate(gpmc_fck)) / 1000);
+       unsigned long rate = clk_get_rate(gpmc_l3_clk);
+
+       if (rate == 0) {
+               printk(KERN_WARNING "gpmc_l3_clk not enabled\n");
+               return 0;
+       }
+
+       rate /= 1000;
+       rate = 1000000000 / rate;       /* In picoseconds */
+
+       return rate;
 }
 
 unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
@@ -110,6 +115,11 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
        return (time_ns * 1000 + tick_ps - 1) / tick_ps;
 }
 
+unsigned int gpmc_ticks_to_ns(unsigned int ticks)
+{
+       return ticks * gpmc_get_fclk_period() / 1000;
+}
+
 unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
 {
        unsigned long ticks = gpmc_ns_to_ticks(time_ns);
@@ -210,6 +220,11 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 
        GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+       if (cpu_is_omap34xx()) {
+               GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+               GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
+       }
+
        /* caller is expected to have initialized CONFIG1 to cover
         * at least sync vs async
         */
@@ -350,6 +365,7 @@ out:
        spin_unlock(&gpmc_mem_lock);
        return r;
 }
+EXPORT_SYMBOL(gpmc_cs_request);
 
 void gpmc_cs_free(int cs)
 {
@@ -365,8 +381,9 @@ void gpmc_cs_free(int cs)
        gpmc_cs_set_reserved(cs, 0);
        spin_unlock(&gpmc_mem_lock);
 }
+EXPORT_SYMBOL(gpmc_cs_free);
 
-void __init gpmc_mem_init(void)
+static void __init gpmc_mem_init(void)
 {
        int cs;
        unsigned long boot_rom_space = 0;
@@ -396,12 +413,33 @@ void __init gpmc_mem_init(void)
 void __init gpmc_init(void)
 {
        u32 l;
+       char *ck;
+
+       if (cpu_is_omap24xx()) {
+               ck = "core_l3_ck";
+               if (cpu_is_omap2420())
+                       l = OMAP2420_GPMC_BASE;
+               else
+                       l = OMAP34XX_GPMC_BASE;
+       } else if (cpu_is_omap34xx()) {
+               ck = "gpmc_fck";
+               l = OMAP34XX_GPMC_BASE;
+       }
 
-       gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
-       if (IS_ERR(gpmc_fck))
-               WARN_ON(1);
-       else
-               clk_enable(gpmc_fck);
+       gpmc_l3_clk = clk_get(NULL, ck);
+       if (IS_ERR(gpmc_l3_clk)) {
+               printk(KERN_ERR "Could not get GPMC clock %s\n", ck);
+               return -ENODEV;
+       }
+
+       gpmc_base = ioremap(l, SZ_4K);
+       if (!gpmc_base) {
+               clk_put(gpmc_l3_clk);
+               printk(KERN_ERR "Could not get GPMC register memory\n");
+               return -ENOMEM;
+       }
+
+       BUG_ON(IS_ERR(gpmc_l3_clk));
 
        l = gpmc_read_reg(GPMC_REVISION);
        printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
index 209177c7f22fe434a442359dd8f54f68d243348e..bf45ff39a7b5fbe9d651fbc81c6ec6f2caeb7e32 100644 (file)
 
 #include <asm/cputype.h>
 
+#include <mach/common.h>
 #include <mach/control.h>
 #include <mach/cpu.h>
 
-#if defined(CONFIG_ARCH_OMAP2420)
-#define TAP_BASE       io_p2v(0x48014000)
-#elif defined(CONFIG_ARCH_OMAP2430)
-#define TAP_BASE       io_p2v(0x4900A000)
-#elif defined(CONFIG_ARCH_OMAP34XX)
-#define TAP_BASE       io_p2v(0x4830A000)
-#endif
+static u32 class;
+static void __iomem *tap_base;
+static u16 tap_prod_id;
 
 #define OMAP_TAP_IDCODE                0x0204
-#if defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP_TAP_PROD_ID       0x0210
-#else
-#define OMAP_TAP_PROD_ID       0x0208
-#endif
-
 #define OMAP_TAP_DIE_ID_0      0x0218
 #define OMAP_TAP_DIE_ID_1      0x021C
 #define OMAP_TAP_DIE_ID_2      0x0220
@@ -94,18 +85,24 @@ static u32 __init read_tap_reg(int reg)
         * it means its Cortex r0p0 which is 3430 ES1
         */
        if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) {
+
+               if (reg == tap_prod_id) {
+                       regval = 0x000F00F0;
+                       goto out;
+               }
+
                switch (reg) {
                case OMAP_TAP_IDCODE  : regval = 0x0B7AE02F; break;
                /* Making DevType as 0xF in ES1 to differ from ES2 */
-               case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break;
                case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break;
                case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break;
                case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break;
                case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break;
                }
        } else
-               regval = __raw_readl(TAP_BASE + reg);
+               regval = __raw_readl(tap_base + reg);
 
+out:
        return regval;
 
 }
@@ -204,7 +201,7 @@ void __init omap2_check_revision(void)
        u8  rev;
 
        idcode = read_tap_reg(OMAP_TAP_IDCODE);
-       prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
+       prod_id = read_tap_reg(tap_prod_id);
        hawkeye = (idcode >> 12) & 0xffff;
        rev = (idcode >> 28) & 0x0f;
        dev_type = (prod_id >> 16) & 0x0f;
@@ -269,3 +266,13 @@ void __init omap2_check_revision(void)
 
 }
 
+void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
+{
+       class = omap2_globals->class;
+       tap_base = omap2_globals->tap;
+
+       if (class == 0x3430)
+               tap_prod_id = 0x0210;
+       else
+               tap_prod_id = 0x0208;
+}
index 7c3d6289c05ff50412b2e4ad75b50ba1ff8c4212..5ea64f926ed592e9348581080ee0bac061ab31a5 100644 (file)
@@ -4,8 +4,11 @@
  * OMAP2 I/O mapping code
  *
  * Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
- * Updated map desc to add 2430 support : <x0khasim@ti.com>
+ * Copyright (C) 2007 Texas Instruments
+ *
+ * Author:
+ *     Juha Yrjola <juha.yrjola@nokia.com>
+ *     Syed Khasim <x0khasim@ti.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
 
 #include <mach/mux.h>
 #include <mach/omapfb.h>
+#include <mach/sram.h>
+
+#include "memory.h"
+
+#include "clock.h"
+
+#include <mach/powerdomain.h>
+
+#include "powerdomains.h"
 
-extern void omap_sram_init(void);
-extern int omap2_clk_init(void);
-extern void omap2_check_revision(void);
-extern void omap2_init_memory(void);
-extern void gpmc_init(void);
-extern void omapfb_reserve_sdram(void);
+#include <mach/clockdomain.h>
+#include "clockdomains.h"
 
 /*
  * The machine specific code may provide the extra mapping besides the
  * default mapping provided here.
  */
-static struct map_desc omap2_io_desc[] __initdata = {
+
+#ifdef CONFIG_ARCH_OMAP24XX
+static struct map_desc omap24xx_io_desc[] __initdata = {
        {
                .virtual        = L3_24XX_VIRT,
                .pfn            = __phys_to_pfn(L3_24XX_PHYS),
@@ -43,12 +53,39 @@ static struct map_desc omap2_io_desc[] __initdata = {
                .type           = MT_DEVICE
        },
        {
-               .virtual        = L4_24XX_VIRT,
-               .pfn            = __phys_to_pfn(L4_24XX_PHYS),
-               .length         = L4_24XX_SIZE,
-               .type           = MT_DEVICE
+               .virtual        = L4_24XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_24XX_PHYS),
+               .length         = L4_24XX_SIZE,
+               .type           = MT_DEVICE
        },
+};
+
+#ifdef CONFIG_ARCH_OMAP2420
+static struct map_desc omap242x_io_desc[] __initdata = {
+       {
+               .virtual        = DSP_MEM_24XX_VIRT,
+               .pfn            = __phys_to_pfn(DSP_MEM_24XX_PHYS),
+               .length         = DSP_MEM_24XX_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = DSP_IPI_24XX_VIRT,
+               .pfn            = __phys_to_pfn(DSP_IPI_24XX_PHYS),
+               .length         = DSP_IPI_24XX_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = DSP_MMU_24XX_VIRT,
+               .pfn            = __phys_to_pfn(DSP_MMU_24XX_PHYS),
+               .length         = DSP_MMU_24XX_SIZE,
+               .type           = MT_DEVICE
+       },
+};
+
+#endif
+
 #ifdef CONFIG_ARCH_OMAP2430
+static struct map_desc omap243x_io_desc[] __initdata = {
        {
                .virtual        = L4_WK_243X_VIRT,
                .pfn            = __phys_to_pfn(L4_WK_243X_PHYS),
@@ -61,30 +98,90 @@ static struct map_desc omap2_io_desc[] __initdata = {
                .length         = OMAP243X_GPMC_SIZE,
                .type           = MT_DEVICE
        },
+       {
+               .virtual        = OMAP243X_SDRC_VIRT,
+               .pfn            = __phys_to_pfn(OMAP243X_SDRC_PHYS),
+               .length         = OMAP243X_SDRC_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = OMAP243X_SMS_VIRT,
+               .pfn            = __phys_to_pfn(OMAP243X_SMS_PHYS),
+               .length         = OMAP243X_SMS_SIZE,
+               .type           = MT_DEVICE
+       },
+};
+#endif
 #endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct map_desc omap34xx_io_desc[] __initdata = {
        {
-               .virtual        = DSP_MEM_24XX_VIRT,
-               .pfn            = __phys_to_pfn(DSP_MEM_24XX_PHYS),
-               .length         = DSP_MEM_24XX_SIZE,
+               .virtual        = L3_34XX_VIRT,
+               .pfn            = __phys_to_pfn(L3_34XX_PHYS),
+               .length         = L3_34XX_SIZE,
                .type           = MT_DEVICE
        },
        {
-               .virtual        = DSP_IPI_24XX_VIRT,
-               .pfn            = __phys_to_pfn(DSP_IPI_24XX_PHYS),
-               .length         = DSP_IPI_24XX_SIZE,
+               .virtual        = L4_34XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_34XX_PHYS),
+               .length         = L4_34XX_SIZE,
                .type           = MT_DEVICE
        },
        {
-               .virtual        = DSP_MMU_24XX_VIRT,
-               .pfn            = __phys_to_pfn(DSP_MMU_24XX_PHYS),
-               .length         = DSP_MMU_24XX_SIZE,
+               .virtual        = L4_WK_34XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_WK_34XX_PHYS),
+               .length         = L4_WK_34XX_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = OMAP34XX_GPMC_VIRT,
+               .pfn            = __phys_to_pfn(OMAP34XX_GPMC_PHYS),
+               .length         = OMAP34XX_GPMC_SIZE,
                .type           = MT_DEVICE
-       }
+       },
+       {
+               .virtual        = OMAP343X_SMS_VIRT,
+               .pfn            = __phys_to_pfn(OMAP343X_SMS_PHYS),
+               .length         = OMAP343X_SMS_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = OMAP343X_SDRC_VIRT,
+               .pfn            = __phys_to_pfn(OMAP343X_SDRC_PHYS),
+               .length         = OMAP343X_SDRC_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = L4_PER_34XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_PER_34XX_PHYS),
+               .length         = L4_PER_34XX_SIZE,
+               .type           = MT_DEVICE
+       },
+       {
+               .virtual        = L4_EMU_34XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_EMU_34XX_PHYS),
+               .length         = L4_EMU_34XX_SIZE,
+               .type           = MT_DEVICE
+       },
 };
+#endif
 
 void __init omap2_map_common_io(void)
 {
-       iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
+#if defined(CONFIG_ARCH_OMAP2420)
+       iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+       iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2430)
+       iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+       iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
+#endif
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+       iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
+#endif
 
        /* Normally devicemaps_init() would flush caches and tlb after
         * mdesc->map_io(), but we must also do it here because of the CPU
@@ -101,12 +198,9 @@ void __init omap2_map_common_io(void)
 void __init omap2_init_common_hw(void)
 {
        omap2_mux_init();
+       pwrdm_init(powerdomains_omap);
+       clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
        omap2_clk_init();
-/*
- * Need to Fix this for 2430
- */
-#ifndef CONFIG_ARCH_OMAP2430
        omap2_init_memory();
-#endif
        gpmc_init();
 }
index 196a9565a8dc206ddcbd567673ba1a5323244b42..d354e0fe4477ad450668b16e462258e26b2b4853 100644 (file)
 #include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach/irq.h>
-#include <asm/irq.h>
 
-#define INTC_REVISION  0x0000
-#define INTC_SYSCONFIG 0x0010
-#define INTC_SYSSTATUS 0x0014
-#define INTC_CONTROL   0x0048
-#define INTC_MIR_CLEAR0        0x0088
-#define INTC_MIR_SET0  0x008c
+
+/* selected INTC register offsets */
+
+#define INTC_REVISION          0x0000
+#define INTC_SYSCONFIG         0x0010
+#define INTC_SYSSTATUS         0x0014
+#define INTC_CONTROL           0x0048
+#define INTC_MIR_CLEAR0                0x0088
+#define INTC_MIR_SET0          0x008c
+#define INTC_PENDING_IRQ0      0x0098
+
+/* Number of IRQ state bits in each MIR register */
+#define IRQ_BITS_PER_REG       32
 
 /*
  * OMAP2 has a number of different interrupt controllers, each interrupt
  * for each bank.. when in doubt, consult the TRM.
  */
 static struct omap_irq_bank {
-       unsigned long base_reg;
+       void __iomem *base_reg;
        unsigned int nr_irqs;
 } __attribute__ ((aligned(4))) irq_banks[] = {
        {
                /* MPU INTC */
-               .base_reg       = IO_ADDRESS(OMAP24XX_IC_BASE),
+               .base_reg       = 0,
                .nr_irqs        = 96,
-       }, {
-               /* XXX: DSP INTC */
-       }
+       },
 };
 
+/* INTC bank register get/set */
+
+static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg)
+{
+       __raw_writel(val, bank->base_reg + reg);
+}
+
+static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg)
+{
+       return __raw_readl(bank->base_reg + reg);
+}
+
 /* XXX: FIQ and additional INTC support (only MPU at the moment) */
 static void omap_ack_irq(unsigned int irq)
 {
-       __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
+       intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
 }
 
 static void omap_mask_irq(unsigned int irq)
 {
-       int offset = (irq >> 5) << 5;
+       int offset = irq & (~(IRQ_BITS_PER_REG - 1));
 
-       if (irq >= 64) {
-               irq %= 64;
-       } else if (irq >= 32) {
-               irq %= 32;
-       }
+       irq &= (IRQ_BITS_PER_REG - 1);
 
-       __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
+       intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset);
 }
 
 static void omap_unmask_irq(unsigned int irq)
 {
-       int offset = (irq >> 5) << 5;
+       int offset = irq & (~(IRQ_BITS_PER_REG - 1));
 
-       if (irq >= 64) {
-               irq %= 64;
-       } else if (irq >= 32) {
-               irq %= 32;
-       }
+       irq &= (IRQ_BITS_PER_REG - 1);
 
-       __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
+       intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset);
 }
 
 static void omap_mask_ack_irq(unsigned int irq)
@@ -93,20 +101,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
 {
        unsigned long tmp;
 
-       tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff;
-       printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
+       tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff;
+       printk(KERN_INFO "IRQ: Found an INTC at 0x%p "
                         "(revision %ld.%ld) with %d interrupts\n",
                         bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
 
-       tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG);
+       tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG);
        tmp |= 1 << 1;  /* soft reset */
-       __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
+       intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG);
 
-       while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
+       while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1))
                /* Wait for reset to complete */;
 
        /* Enable autoidle */
-       __raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG);
+       intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG);
 }
 
 void __init omap_init_irq(void)
@@ -118,9 +126,10 @@ void __init omap_init_irq(void)
        for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
                struct omap_irq_bank *bank = irq_banks + i;
 
-               /* XXX */
-               if (!bank->base_reg)
-                       continue;
+               if (cpu_is_omap24xx())
+                       bank->base_reg = OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE);
+               else if (cpu_is_omap34xx())
+                       bank->base_reg = OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE);
 
                omap_irq_bank_init_one(bank);
 
index b261f1f80b5e0fd7131a5586ca04bb6d9796a3ea..cae3ebe249b3cdbacb18ece2b34e06aba82d17d5 100644 (file)
@@ -89,6 +89,30 @@ static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
                        .disable        = omap_mcbsp_clk_disable,
                },
        },
+       {
+               .clk = {
+                       .name           = "mcbsp_clk",
+                       .id             = 3,
+                       .enable         = omap_mcbsp_clk_enable,
+                       .disable        = omap_mcbsp_clk_disable,
+               },
+       },
+       {
+               .clk = {
+                       .name           = "mcbsp_clk",
+                       .id             = 4,
+                       .enable         = omap_mcbsp_clk_enable,
+                       .disable        = omap_mcbsp_clk_disable,
+               },
+       },
+       {
+               .clk = {
+                       .name           = "mcbsp_clk",
+                       .id             = 5,
+                       .enable         = omap_mcbsp_clk_enable,
+                       .disable        = omap_mcbsp_clk_disable,
+               },
+       },
 };
 
 #define omap_mcbsp_clks_size   ARRAY_SIZE(omap_mcbsp_clks)
@@ -117,25 +141,14 @@ static void omap2_mcbsp_request(unsigned int id)
                omap2_mcbsp2_mux_setup();
 }
 
-static int omap2_mcbsp_check(unsigned int id)
-{
-       if (id > OMAP_MAX_MCBSP_COUNT - 1) {
-               printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
-               return -ENODEV;
-       }
-       return 0;
-}
-
 static struct omap_mcbsp_ops omap2_mcbsp_ops = {
        .request        = omap2_mcbsp_request,
-       .check          = omap2_mcbsp_check,
 };
 
-#ifdef CONFIG_ARCH_OMAP24XX
-static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
+#ifdef CONFIG_ARCH_OMAP2420
+static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
        {
                .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .virt_base      = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
                .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
                .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
@@ -145,7 +158,6 @@ static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
        },
        {
                .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .virt_base      = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
                .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
                .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
@@ -154,17 +166,70 @@ static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
                .clk_name       = "mcbsp_clk",
        },
 };
-#define OMAP24XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap24xx_mcbsp_pdata)
+#define OMAP2420_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2420_mcbsp_pdata)
 #else
-#define omap24xx_mcbsp_pdata           NULL
-#define OMAP24XX_MCBSP_PDATA_SZ                0
+#define omap2420_mcbsp_pdata           NULL
+#define OMAP2420_MCBSP_PDATA_SZ                0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
+       {
+               .phys_base      = OMAP24XX_MCBSP1_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
+               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+       {
+               .phys_base      = OMAP24XX_MCBSP2_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
+               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+       {
+               .phys_base      = OMAP2430_MCBSP3_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
+               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+       {
+               .phys_base      = OMAP2430_MCBSP4_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
+               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+       {
+               .phys_base      = OMAP2430_MCBSP5_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
+               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+};
+#define OMAP2430_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2430_mcbsp_pdata)
+#else
+#define omap2430_mcbsp_pdata           NULL
+#define OMAP2430_MCBSP_PDATA_SZ                0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP34XX
 static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
        {
                .phys_base      = OMAP34XX_MCBSP1_BASE,
-               .virt_base      = IO_ADDRESS(OMAP34XX_MCBSP1_BASE),
                .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
                .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
@@ -174,7 +239,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
        },
        {
                .phys_base      = OMAP34XX_MCBSP2_BASE,
-               .virt_base      = IO_ADDRESS(OMAP34XX_MCBSP2_BASE),
                .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
                .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
@@ -182,6 +246,33 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
                .ops            = &omap2_mcbsp_ops,
                .clk_name       = "mcbsp_clk",
        },
+       {
+               .phys_base      = OMAP34XX_MCBSP3_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
+               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+       {
+               .phys_base      = OMAP34XX_MCBSP4_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
+               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
+       {
+               .phys_base      = OMAP34XX_MCBSP5_BASE,
+               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
+               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
+               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+               .clk_name       = "mcbsp_clk",
+       },
 };
 #define OMAP34XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap34xx_mcbsp_pdata)
 #else
@@ -189,7 +280,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 #define OMAP34XX_MCBSP_PDATA_SZ                0
 #endif
 
-int __init omap2_mcbsp_init(void)
+static int __init omap2_mcbsp_init(void)
 {
        int i;
 
@@ -199,10 +290,24 @@ int __init omap2_mcbsp_init(void)
                clk_register(&omap_mcbsp_clks[i].clk);
        }
 
-       if (cpu_is_omap24xx())
-               omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata,
-                                               OMAP24XX_MCBSP_PDATA_SZ);
+       if (cpu_is_omap2420())
+               omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
+       if (cpu_is_omap2430())
+               omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
+       if (cpu_is_omap34xx())
+               omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
+
+       mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
+                                                               GFP_KERNEL);
+       if (!mcbsp_ptr)
+               return -ENOMEM;
 
+       if (cpu_is_omap2420())
+               omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
+                                               OMAP2420_MCBSP_PDATA_SZ);
+       if (cpu_is_omap2430())
+               omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
+                                               OMAP2430_MCBSP_PDATA_SZ);
        if (cpu_is_omap34xx())
                omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
                                                OMAP34XX_MCBSP_PDATA_SZ);
index ab1462b02e6e97f9ce306bc878a5b7782ebf38f0..882c7022429260a291b60221b2ee587098608a22 100644 (file)
@@ -101,6 +101,17 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force)
        return prev;
 }
 
+#if !defined(CONFIG_ARCH_OMAP2)
+void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+                               u32 base_cs, u32 force_unlock)
+{
+}
+void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+                                     u32 mem_type)
+{
+}
+#endif
+
 void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
 {
        unsigned long dll_cnt;
@@ -165,6 +176,9 @@ void __init omap2_init_memory(void)
 {
        u32 l;
 
+       if (!cpu_is_omap2420())
+               return;
+
        l = sms_read_reg(SMS_SYSCONFIG);
        l &= ~(0x3 << 3);
        l |= (0x2 << 3);
index 9a280b50a89306e977771e55dc3c0793d58980f2..bb3db80a7c46105861fe7f908139d740802dcac4 100644 (file)
@@ -14,6 +14,9 @@
  * published by the Free Software Foundation.
  */
 
+#ifndef ARCH_ARM_MACH_OMAP2_MEMORY_H
+#define ARCH_ARM_MACH_OMAP2_MEMORY_H
+
 /* Memory timings */
 #define M_DDR          1
 #define M_LOCK_CTRL    (1 << 2)
@@ -34,3 +37,7 @@ extern u32 omap2_memory_get_fast_dll_ctrl(void);
 extern u32 omap2_memory_get_type(void);
 u32 omap2_dll_force_needed(void);
 u32 omap2_reprogram_sdrc(u32 level, u32 force);
+void __init omap2_init_memory(void);
+void __init gpmc_init(void);
+
+#endif
index 6b7d672058b9b360ff1b4034c070f3ab64091e00..b1393673d95d802b97f2a24494cddad16340de0d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-omap2/mux.c
  *
- * OMAP2 pin multiplexing configurations
+ * OMAP2 and OMAP3 pin multiplexing configurations
  *
  * Copyright (C) 2004 - 2008 Texas Instruments Inc.
  * Copyright (C) 2003 - 2008 Nokia Corporation
@@ -220,16 +220,222 @@ MUX_CFG_24XX("AD13_2430_MCBSP2_DR_OFF",  0x0131, 0,      0,      0,      1)
 #define OMAP24XX_PINS_SZ       0
 #endif /* CONFIG_ARCH_OMAP24XX */
 
-#define OMAP24XX_PULL_ENA      (1 << 3)
-#define OMAP24XX_PULL_UP       (1 << 4)
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct pin_config __initdata_or_module omap34xx_pins[] = {
+/*
+ *             Name, reg-offset,
+ *             mux-mode | [active-mode | off-mode]
+ */
+
+/* 34xx I2C */
+MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+
+/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
+MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
+MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB11_3430_USB2HS_PHY_NXT", 0x5f6,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB10_3430_USB2HS_PHY_D0", 0x5f8,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB9_3430_USB2HS_PHY_D1", 0x5fa,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W3_3430_USB2HS_PHY_D2", 0x1d4,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T4_3430_USB2HS_PHY_D3", 0x1de,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T3_3430_USB2HS_PHY_D4", 0x1d8,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R3_3430_USB2HS_PHY_D5", 0x1da,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R4_3430_USB2HS_PHY_D6", 0x1dc,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T2_3430_USB2HS_PHY_D7", 0x1d6,
+               OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* TLL - HSUSB: 12-pin TLL Port 1*/
+MUX_CFG_34XX("Y8_3430_USB1HS_TLL_CLK", 0x5da,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y9_3430_USB1HS_TLL_STP", 0x5d8,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AA14_3430_USB1HS_TLL_DIR", 0x5ec,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA11_3430_USB1HS_TLL_NXT", 0x5ee,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W13_3430_USB1HS_TLL_D0", 0x5dc,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W12_3430_USB1HS_TLL_D1", 0x5de,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W11_3430_USB1HS_TLL_D2", 0x5e0,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y11_3430_USB1HS_TLL_D3", 0x5ea,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W9_3430_USB1HS_TLL_D4", 0x5e4,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y12_3430_USB1HS_TLL_D5", 0x5e6,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W8_3430_USB1HS_TLL_D6", 0x5e8,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y13_3430_USB1HS_TLL_D7", 0x5e2,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* TLL - HSUSB: 12-pin TLL Port 2*/
+MUX_CFG_34XX("AA8_3430_USB2HS_TLL_CLK", 0x5f0,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA10_3430_USB2HS_TLL_STP", 0x5f2,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AA9_3430_USB2HS_TLL_DIR", 0x5f4,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB11_3430_USB2HS_TLL_NXT", 0x5f6,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB10_3430_USB2HS_TLL_D0", 0x5f8,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB9_3430_USB2HS_TLL_D1", 0x5fa,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W3_3430_USB2HS_TLL_D2", 0x1d4,
+               OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T4_3430_USB2HS_TLL_D3", 0x1de,
+               OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T3_3430_USB2HS_TLL_D4", 0x1d8,
+               OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R3_3430_USB2HS_TLL_D5", 0x1da,
+               OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R4_3430_USB2HS_TLL_D6", 0x1dc,
+               OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T2_3430_USB2HS_TLL_D7", 0x1d6,
+               OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* TLL - HSUSB: 12-pin TLL Port 3*/
+MUX_CFG_34XX("AA6_3430_USB3HS_TLL_CLK", 0x180,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB3_3430_USB3HS_TLL_STP", 0x166,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AA3_3430_USB3HS_TLL_DIR", 0x168,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y3_3430_USB3HS_TLL_NXT", 0x16a,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA5_3430_USB3HS_TLL_D0", 0x186,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y4_3430_USB3HS_TLL_D1", 0x184,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y5_3430_USB3HS_TLL_D2", 0x188,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W5_3430_USB3HS_TLL_D3", 0x18a,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB12_3430_USB3HS_TLL_D4", 0x16c,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB13_3430_USB3HS_TLL_D5", 0x16e,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA13_3430_USB3HS_TLL_D6", 0x170,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA12_3430_USB3HS_TLL_D7", 0x172,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
+MUX_CFG_34XX("AF10_3430_USB1FS_PHY_MM1_RXDP", 0x5d8,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AG9_3430_USB1FS_PHY_MM1_RXDM", 0x5ee,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W13_3430_USB1FS_PHY_MM1_RXRCV", 0x5dc,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W12_3430_USB1FS_PHY_MM1_TXSE0", 0x5de,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W11_3430_USB1FS_PHY_MM1_TXDAT", 0x5e0,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y11_3430_USB1FS_PHY_MM1_TXEN_N", 0x5ea,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT)
+
+/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
+MUX_CFG_34XX("AF7_3430_USB2FS_PHY_MM2_RXDP", 0x5f2,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AH7_3430_USB2FS_PHY_MM2_RXDM", 0x5f6,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB10_3430_USB2FS_PHY_MM2_RXRCV", 0x5f8,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB9_3430_USB2FS_PHY_MM2_TXSE0", 0x5fa,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W3_3430_USB2FS_PHY_MM2_TXDAT", 0x1d4,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T4_3430_USB2FS_PHY_MM2_TXEN_N", 0x1de,
+               OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT)
+
+/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
+MUX_CFG_34XX("AH3_3430_USB3FS_PHY_MM3_RXDP", 0x166,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AE3_3430_USB3FS_PHY_MM3_RXDM", 0x16a,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AD1_3430_USB3FS_PHY_MM3_RXRCV", 0x186,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AE1_3430_USB3FS_PHY_MM3_TXSE0", 0x184,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AD2_3430_USB3FS_PHY_MM3_TXDAT", 0x188,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a,
+               OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_OUTPUT)
+
+};
+
+#define OMAP34XX_PINS_SZ       ARRAY_SIZE(omap34xx_pins)
+
+#else
+#define omap34xx_pins          NULL
+#define OMAP34XX_PINS_SZ       0
+#endif /* CONFIG_ARCH_OMAP34XX */
 
 #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
-void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg)
+static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg)
 {
        u16 orig;
        u8 warn = 0, debug = 0;
 
-       orig = omap_ctrl_readb(cfg->mux_reg);
+       if (cpu_is_omap24xx())
+               orig = omap_ctrl_readb(cfg->mux_reg);
+       else
+               orig = omap_ctrl_readw(cfg->mux_reg);
 
 #ifdef CONFIG_OMAP_MUX_DEBUG
        debug = cfg->debug;
@@ -255,9 +461,9 @@ int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg)
        spin_lock_irqsave(&mux_spin_lock, flags);
        reg |= cfg->mask & 0x7;
        if (cfg->pull_val)
-               reg |= OMAP24XX_PULL_ENA;
+               reg |= OMAP2_PULL_ENA;
        if (cfg->pu_pd_val)
-               reg |= OMAP24XX_PULL_UP;
+               reg |= OMAP2_PULL_UP;
        omap2_cfg_debug(cfg, reg);
        omap_ctrl_writeb(reg, cfg->mux_reg);
        spin_unlock_irqrestore(&mux_spin_lock, flags);
@@ -265,7 +471,26 @@ int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg)
        return 0;
 }
 #else
-#define omap24xx_cfg_reg       0
+#define omap24xx_cfg_reg       NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg)
+{
+       static DEFINE_SPINLOCK(mux_spin_lock);
+       unsigned long flags;
+       u16 reg = 0;
+
+       spin_lock_irqsave(&mux_spin_lock, flags);
+       reg |= cfg->mux_val;
+       omap2_cfg_debug(cfg, reg);
+       omap_ctrl_writew(reg, cfg->mux_reg);
+       spin_unlock_irqrestore(&mux_spin_lock, flags);
+
+       return 0;
+}
+#else
+#define omap34xx_cfg_reg       NULL
 #endif
 
 int __init omap2_mux_init(void)
@@ -274,6 +499,10 @@ int __init omap2_mux_init(void)
                arch_mux_cfg.pins       = omap24xx_pins;
                arch_mux_cfg.size       = OMAP24XX_PINS_SZ;
                arch_mux_cfg.cfg_reg    = omap24xx_cfg_reg;
+       } else if (cpu_is_omap34xx()) {
+               arch_mux_cfg.pins       = omap34xx_pins;
+               arch_mux_cfg.size       = OMAP34XX_PINS_SZ;
+               arch_mux_cfg.cfg_reg    = omap34xx_cfg_reg;
        }
 
        return omap_mux_register(&arch_mux_cfg);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
new file mode 100644 (file)
index 0000000..73e2971
--- /dev/null
@@ -0,0 +1,1113 @@
+/*
+ * OMAP powerdomain control
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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.
+ */
+#ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN
+# define DEBUG
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/atomic.h>
+
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+
+#include <mach/cpu.h>
+#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
+
+/* pwrdm_list contains all registered struct powerdomains */
+static LIST_HEAD(pwrdm_list);
+
+/*
+ * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to
+ * protect pwrdm_clkdms[] during clkdm add/del ops
+ */
+static DEFINE_RWLOCK(pwrdm_rwlock);
+
+
+/* Private functions */
+
+static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+       u32 v;
+
+       v = prm_read_mod_reg(domain, idx);
+       v &= mask;
+       v >>= __ffs(mask);
+
+       return v;
+}
+
+static struct powerdomain *_pwrdm_lookup(const char *name)
+{
+       struct powerdomain *pwrdm, *temp_pwrdm;
+
+       pwrdm = NULL;
+
+       list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
+               if (!strcmp(name, temp_pwrdm->name)) {
+                       pwrdm = temp_pwrdm;
+                       break;
+               }
+       }
+
+       return pwrdm;
+}
+
+/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
+static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
+                                             struct pwrdm_dep *deps)
+{
+       struct pwrdm_dep *pd;
+
+       if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
+               return ERR_PTR(-EINVAL);
+
+       for (pd = deps; pd; pd++) {
+
+               if (!omap_chip_is(pd->omap_chip))
+                       continue;
+
+               if (!pd->pwrdm && pd->pwrdm_name)
+                       pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
+
+               if (pd->pwrdm == pwrdm)
+                       break;
+
+       }
+
+       if (!pd)
+               return ERR_PTR(-ENOENT);
+
+       return pd->pwrdm;
+}
+
+
+/* Public functions */
+
+/**
+ * pwrdm_init - set up the powerdomain layer
+ *
+ * Loop through the list of powerdomains, registering all that are
+ * available on the current CPU. If pwrdm_list is supplied and not
+ * null, all of the referenced powerdomains will be registered.  No
+ * return value.
+ */
+void pwrdm_init(struct powerdomain **pwrdm_list)
+{
+       struct powerdomain **p = NULL;
+
+       if (pwrdm_list)
+               for (p = pwrdm_list; *p; p++)
+                       pwrdm_register(*p);
+}
+
+/**
+ * pwrdm_register - register a powerdomain
+ * @pwrdm: struct powerdomain * to register
+ *
+ * Adds a powerdomain to the internal powerdomain list.  Returns
+ * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+int pwrdm_register(struct powerdomain *pwrdm)
+{
+       unsigned long flags;
+       int ret = -EINVAL;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (!omap_chip_is(pwrdm->omap_chip))
+               return -EINVAL;
+
+       write_lock_irqsave(&pwrdm_rwlock, flags);
+       if (_pwrdm_lookup(pwrdm->name)) {
+               ret = -EEXIST;
+               goto pr_unlock;
+       }
+
+       list_add(&pwrdm->node, &pwrdm_list);
+
+       pr_debug("powerdomain: registered %s\n", pwrdm->name);
+       ret = 0;
+
+pr_unlock:
+       write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       return ret;
+}
+
+/**
+ * pwrdm_unregister - unregister a powerdomain
+ * @pwrdm: struct powerdomain * to unregister
+ *
+ * Removes a powerdomain from the internal powerdomain list.  Returns
+ * -EINVAL if pwrdm argument is NULL.
+ */
+int pwrdm_unregister(struct powerdomain *pwrdm)
+{
+       unsigned long flags;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       write_lock_irqsave(&pwrdm_rwlock, flags);
+       list_del(&pwrdm->node);
+       write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
+
+       return 0;
+}
+
+/**
+ * pwrdm_lookup - look up a powerdomain by name, return a pointer
+ * @name: name of powerdomain
+ *
+ * Find a registered powerdomain by its name.  Returns a pointer to the
+ * struct powerdomain if found, or NULL otherwise.
+ */
+struct powerdomain *pwrdm_lookup(const char *name)
+{
+       struct powerdomain *pwrdm;
+       unsigned long flags;
+
+       if (!name)
+               return NULL;
+
+       read_lock_irqsave(&pwrdm_rwlock, flags);
+       pwrdm = _pwrdm_lookup(name);
+       read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       return pwrdm;
+}
+
+/**
+ * pwrdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * Call the supplied function for each registered powerdomain.  The
+ * callback function can return anything but 0 to bail out early from
+ * the iterator.  The callback function is called with the pwrdm_rwlock
+ * held for reading, so no powerdomain structure manipulation
+ * functions should be called from the callback, although hardware
+ * powerdomain control functions are fine.  Returns the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure; or -EINVAL if the function
+ * pointer is null.
+ */
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
+{
+       struct powerdomain *temp_pwrdm;
+       unsigned long flags;
+       int ret = 0;
+
+       if (!fn)
+               return -EINVAL;
+
+       read_lock_irqsave(&pwrdm_rwlock, flags);
+       list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
+               ret = (*fn)(temp_pwrdm);
+               if (ret)
+                       break;
+       }
+       read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       return ret;
+}
+
+/**
+ * pwrdm_add_clkdm - add a clockdomain to a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'.  This
+ * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
+ * presented with invalid pointers; -ENOMEM if memory could not be allocated;
+ * or 0 upon success.
+ */
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+       unsigned long flags;
+       int i;
+       int ret = -EINVAL;
+
+       if (!pwrdm || !clkdm)
+               return -EINVAL;
+
+       pr_debug("powerdomain: associating clockdomain %s with powerdomain "
+                "%s\n", clkdm->name, pwrdm->name);
+
+       write_lock_irqsave(&pwrdm_rwlock, flags);
+
+       for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
+               if (!pwrdm->pwrdm_clkdms[i])
+                       break;
+#ifdef DEBUG
+               if (pwrdm->pwrdm_clkdms[i] == clkdm) {
+                       ret = -EINVAL;
+                       goto pac_exit;
+               }
+#endif
+       }
+
+       if (i == PWRDM_MAX_CLKDMS) {
+               pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
+                        "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
+               WARN_ON(1);
+               ret = -ENOMEM;
+               goto pac_exit;
+       }
+
+       pwrdm->pwrdm_clkdms[i] = clkdm;
+
+       ret = 0;
+
+pac_exit:
+       write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       return ret;
+}
+
+/**
+ * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Dissociate the clockdomain 'clkdm' from the powerdomain
+ * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
+ * -ENOENT if the clkdm was not associated with the powerdomain, or 0
+ * upon success.
+ */
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+       unsigned long flags;
+       int ret = -EINVAL;
+       int i;
+
+       if (!pwrdm || !clkdm)
+               return -EINVAL;
+
+       pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
+                "%s\n", clkdm->name, pwrdm->name);
+
+       write_lock_irqsave(&pwrdm_rwlock, flags);
+
+       for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
+               if (pwrdm->pwrdm_clkdms[i] == clkdm)
+                       break;
+
+       if (i == PWRDM_MAX_CLKDMS) {
+               pr_debug("powerdomain: clkdm %s not associated with pwrdm "
+                        "%s ?!\n", clkdm->name, pwrdm->name);
+               ret = -ENOENT;
+               goto pdc_exit;
+       }
+
+       pwrdm->pwrdm_clkdms[i] = NULL;
+
+       ret = 0;
+
+pdc_exit:
+       write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       return ret;
+}
+
+/**
+ * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
+ * @pwrdm: struct powerdomain * to iterate over
+ * @fn: callback function *
+ *
+ * Call the supplied function for each clockdomain in the powerdomain
+ * 'pwrdm'.  The callback function can return anything but 0 to bail
+ * out early from the iterator.  The callback function is called with
+ * the pwrdm_rwlock held for reading, so no powerdomain structure
+ * manipulation functions should be called from the callback, although
+ * hardware powerdomain control functions are fine.  Returns -EINVAL
+ * if presented with invalid pointers; or passes along the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure.
+ */
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+                        int (*fn)(struct powerdomain *pwrdm,
+                                  struct clockdomain *clkdm))
+{
+       unsigned long flags;
+       int ret = 0;
+       int i;
+
+       if (!fn)
+               return -EINVAL;
+
+       read_lock_irqsave(&pwrdm_rwlock, flags);
+
+       for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
+               ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
+
+       read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+       return ret;
+}
+
+
+/**
+ * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: wake this struct powerdomain * up (dependent)
+ * @pwrdm2: when this struct powerdomain * wakes up (source)
+ *
+ * When the powerdomain represented by pwrdm2 wakes up (due to an
+ * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP,
+ * this feature is designed to reduce wakeup latency of the dependent
+ * powerdomain.  Returns -EINVAL if presented with invalid powerdomain
+ * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+       struct powerdomain *p;
+
+       if (!pwrdm1)
+               return -EINVAL;
+
+       p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
+       if (IS_ERR(p)) {
+               pr_debug("powerdomain: hardware cannot set/clear wake up of "
+                        "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
+               return IS_ERR(p);
+       }
+
+       pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
+                pwrdm1->name, pwrdm2->name);
+
+       prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
+                            pwrdm1->prcm_offs, PM_WKDEP);
+
+       return 0;
+}
+
+/**
+ * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: wake this struct powerdomain * up (dependent)
+ * @pwrdm2: when this struct powerdomain * wakes up (source)
+ *
+ * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
+ * wakes up.  Returns -EINVAL if presented with invalid powerdomain
+ * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+       struct powerdomain *p;
+
+       if (!pwrdm1)
+               return -EINVAL;
+
+       p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
+       if (IS_ERR(p)) {
+               pr_debug("powerdomain: hardware cannot set/clear wake up of "
+                        "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
+               return IS_ERR(p);
+       }
+
+       pr_debug("powerdomain: hardware will no longer wake up %s after %s "
+                "wakes up\n", pwrdm1->name, pwrdm2->name);
+
+       prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
+                              pwrdm1->prcm_offs, PM_WKDEP);
+
+       return 0;
+}
+
+/**
+ * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
+ * @pwrdm1: wake this struct powerdomain * up (dependent)
+ * @pwrdm2: when this struct powerdomain * wakes up (source)
+ *
+ * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
+ * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
+ * if either powerdomain pointer is invalid; or -ENOENT if the hardware
+ * is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * wakeup dependencies.  Wakeup dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+       struct powerdomain *p;
+
+       if (!pwrdm1)
+               return -EINVAL;
+
+       p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
+       if (IS_ERR(p)) {
+               pr_debug("powerdomain: hardware cannot set/clear wake up of "
+                        "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
+               return IS_ERR(p);
+       }
+
+       return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
+                                       (1 << pwrdm2->dep_bit));
+}
+
+/**
+ * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
+ * @pwrdm2: when this struct powerdomain * is active (source)
+ *
+ * Prevent pwrdm1 from automatically going inactive (and then to
+ * retention or off) if pwrdm2 is still active.         Returns -EINVAL if
+ * presented with invalid powerdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep dependencies,
+ * -ENOENT if the specified dependency cannot be set in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+       struct powerdomain *p;
+
+       if (!pwrdm1)
+               return -EINVAL;
+
+       if (!cpu_is_omap34xx())
+               return -EINVAL;
+
+       p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
+       if (IS_ERR(p)) {
+               pr_debug("powerdomain: hardware cannot set/clear sleep "
+                        "dependency affecting %s from %s\n", pwrdm1->name,
+                        pwrdm2->name);
+               return IS_ERR(p);
+       }
+
+       pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
+                pwrdm1->name, pwrdm2->name);
+
+       cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
+                           pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
+
+       return 0;
+}
+
+/**
+ * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
+ * @pwrdm2: when this struct powerdomain * is active (source)
+ *
+ * Allow pwrdm1 to automatically go inactive (and then to retention or
+ * off), independent of the activity state of pwrdm2.  Returns -EINVAL
+ * if presented with invalid powerdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep dependencies,
+ * -ENOENT if the specified dependency cannot be cleared in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+       struct powerdomain *p;
+
+       if (!pwrdm1)
+               return -EINVAL;
+
+       if (!cpu_is_omap34xx())
+               return -EINVAL;
+
+       p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
+       if (IS_ERR(p)) {
+               pr_debug("powerdomain: hardware cannot set/clear sleep "
+                        "dependency affecting %s from %s\n", pwrdm1->name,
+                        pwrdm2->name);
+               return IS_ERR(p);
+       }
+
+       pr_debug("powerdomain: will no longer prevent %s from sleeping if "
+                "%s is active\n", pwrdm1->name, pwrdm2->name);
+
+       cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
+                             pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
+
+       return 0;
+}
+
+/**
+ * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
+ * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
+ * @pwrdm2: when this struct powerdomain * is active (source)
+ *
+ * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
+ * not be allowed to automatically go inactive if pwrdm2 is active;
+ * 0 if pwrdm1's automatic power state inactivity transition is independent
+ * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
+ * on a machine that does not support software-configurable hardware sleep
+ * dependencies; or -ENOENT if the hardware is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * sleep dependencies. Sleep dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+       struct powerdomain *p;
+
+       if (!pwrdm1)
+               return -EINVAL;
+
+       if (!cpu_is_omap34xx())
+               return -EINVAL;
+
+       p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
+       if (IS_ERR(p)) {
+               pr_debug("powerdomain: hardware cannot set/clear sleep "
+                        "dependency affecting %s from %s\n", pwrdm1->name,
+                        pwrdm2->name);
+               return IS_ERR(p);
+       }
+
+       return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
+                                       (1 << pwrdm2->dep_bit));
+}
+
+/**
+ * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
+ * @pwrdm: struct powerdomain *
+ *
+ * Return the number of controllable memory banks in powerdomain pwrdm,
+ * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
+ */
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       return pwrdm->banks;
+}
+
+/**
+ * pwrdm_set_next_pwrst - set next powerdomain power state
+ * @pwrdm: struct powerdomain * to set
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the powerdomain pwrdm's next power state to pwrst.  The powerdomain
+ * may not enter this state immediately if the preconditions for this state
+ * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
+ * null or if the power state is invalid for the powerdomin, or returns 0
+ * upon success.
+ */
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (!(pwrdm->pwrsts & (1 << pwrst)))
+               return -EINVAL;
+
+       pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
+                pwrdm->name, pwrst);
+
+       prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+                            (pwrst << OMAP_POWERSTATE_SHIFT),
+                            pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       return 0;
+}
+
+/**
+ * pwrdm_read_next_pwrst - get next powerdomain power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain pwrdm's next power state.  Returns -EINVAL
+ * if the powerdomain pointer is null or returns the next power state
+ * upon success.
+ */
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
+                                       OMAP_POWERSTATE_MASK);
+}
+
+/**
+ * pwrdm_read_pwrst - get current powerdomain power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain pwrdm's current power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the current power state
+ * upon success.
+ */
+int pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
+                                       OMAP_POWERSTATEST_MASK);
+}
+
+/**
+ * pwrdm_read_prev_pwrst - get previous powerdomain power state
+ * @pwrdm: struct powerdomain * to get previous power state
+ *
+ * Return the powerdomain pwrdm's previous power state.  Returns -EINVAL
+ * if the powerdomain pointer is null or returns the previous power state
+ * upon success.
+ */
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
+                                       OMAP3430_LASTPOWERSTATEENTERED_MASK);
+}
+
+/**
+ * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
+ * @pwrdm: struct powerdomain * to set
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state that the logic portion of the powerdomain
+ * pwrdm will enter when the powerdomain enters retention.  This will
+ * be either RETENTION or OFF, if supported.  Returns -EINVAL if the
+ * powerdomain pointer is null or the target power state is not not
+ * supported, or returns 0 upon success.
+ */
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
+               return -EINVAL;
+
+       pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
+                pwrdm->name, pwrst);
+
+       /*
+        * The register bit names below may not correspond to the
+        * actual names of the bits in each powerdomain's register,
+        * but the type of value returned is the same for each
+        * powerdomain.
+        */
+       prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
+                            (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
+                            pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       return 0;
+}
+
+/**
+ * pwrdm_set_mem_onst - set memory power state while powerdomain ON
+ * @pwrdm: struct powerdomain * to set
+ * @bank: memory bank number to set (0-3)
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state that memory bank x of the powerdomain
+ * pwrdm will enter when the powerdomain enters the ON state.  Bank
+ * will be a number from 0 to 3, and represents different types of
+ * memory, depending on the powerdomain.  Returns -EINVAL if the
+ * powerdomain pointer is null or the target power state is not not
+ * supported for this memory bank, -EEXIST if the target memory bank
+ * does not exist or is not controllable, or returns 0 upon success.
+ */
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
+{
+       u32 m;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (pwrdm->banks < (bank + 1))
+               return -EEXIST;
+
+       if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
+               return -EINVAL;
+
+       pr_debug("powerdomain: setting next memory powerstate for domain %s "
+                "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
+
+       /*
+        * The register bit names below may not correspond to the
+        * actual names of the bits in each powerdomain's register,
+        * but the type of value returned is the same for each
+        * powerdomain.
+        */
+       switch (bank) {
+       case 0:
+               m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
+               break;
+       case 1:
+               m = OMAP3430_L1FLATMEMONSTATE_MASK;
+               break;
+       case 2:
+               m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
+               break;
+       case 3:
+               m = OMAP3430_L2FLATMEMONSTATE_MASK;
+               break;
+       default:
+               WARN_ON(1); /* should never happen */
+               return -EEXIST;
+       }
+
+       prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
+                            pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       return 0;
+}
+
+/**
+ * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
+ * @pwrdm: struct powerdomain * to set
+ * @bank: memory bank number to set (0-3)
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state that memory bank x of the powerdomain
+ * pwrdm will enter when the powerdomain enters the RETENTION state.
+ * Bank will be a number from 0 to 3, and represents different types
+ * of memory, depending on the powerdomain.  pwrst will be either
+ * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
+ * pointer is null or the target power state is not not supported for
+ * this memory bank, -EEXIST if the target memory bank does not exist
+ * or is not controllable, or returns 0 upon success.
+ */
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
+{
+       u32 m;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (pwrdm->banks < (bank + 1))
+               return -EEXIST;
+
+       if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
+               return -EINVAL;
+
+       pr_debug("powerdomain: setting next memory powerstate for domain %s "
+                "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
+
+       /*
+        * The register bit names below may not correspond to the
+        * actual names of the bits in each powerdomain's register,
+        * but the type of value returned is the same for each
+        * powerdomain.
+        */
+       switch (bank) {
+       case 0:
+               m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
+               break;
+       case 1:
+               m = OMAP3430_L1FLATMEMRETSTATE;
+               break;
+       case 2:
+               m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
+               break;
+       case 3:
+               m = OMAP3430_L2FLATMEMRETSTATE;
+               break;
+       default:
+               WARN_ON(1); /* should never happen */
+               return -EEXIST;
+       }
+
+       prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+                            PM_PWSTCTRL);
+
+       return 0;
+}
+
+/**
+ * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
+ * @pwrdm: struct powerdomain * to get current logic retention power state
+ *
+ * Return the current power state that the logic portion of
+ * powerdomain pwrdm will enter
+ * Returns -EINVAL if the powerdomain pointer is null or returns the
+ * current logic retention power state upon success.
+ */
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
+                                       OMAP3430_LOGICSTATEST);
+}
+
+/**
+ * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
+ * @pwrdm: struct powerdomain * to get previous logic power state
+ *
+ * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
+ * if the powerdomain pointer is null or returns the previous logic
+ * power state upon success.
+ */
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       /*
+        * The register bit names below may not correspond to the
+        * actual names of the bits in each powerdomain's register,
+        * but the type of value returned is the same for each
+        * powerdomain.
+        */
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
+                                       OMAP3430_LASTLOGICSTATEENTERED);
+}
+
+/**
+ * pwrdm_read_mem_pwrst - get current memory bank power state
+ * @pwrdm: struct powerdomain * to get current memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain pwrdm's current memory power state for bank
+ * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the current memory power state upon success.
+ */
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+       u32 m;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (pwrdm->banks < (bank + 1))
+               return -EEXIST;
+
+       /*
+        * The register bit names below may not correspond to the
+        * actual names of the bits in each powerdomain's register,
+        * but the type of value returned is the same for each
+        * powerdomain.
+        */
+       switch (bank) {
+       case 0:
+               m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
+               break;
+       case 1:
+               m = OMAP3430_L1FLATMEMSTATEST_MASK;
+               break;
+       case 2:
+               m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
+               break;
+       case 3:
+               m = OMAP3430_L2FLATMEMSTATEST_MASK;
+               break;
+       default:
+               WARN_ON(1); /* should never happen */
+               return -EEXIST;
+       }
+
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
+}
+
+/**
+ * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
+ * @pwrdm: struct powerdomain * to get previous memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain pwrdm's previous memory power state for bank
+ * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the previous memory power state upon success.
+ */
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+       u32 m;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (pwrdm->banks < (bank + 1))
+               return -EEXIST;
+
+       /*
+        * The register bit names below may not correspond to the
+        * actual names of the bits in each powerdomain's register,
+        * but the type of value returned is the same for each
+        * powerdomain.
+        */
+       switch (bank) {
+       case 0:
+               m = OMAP3430_LASTMEM1STATEENTERED_MASK;
+               break;
+       case 1:
+               m = OMAP3430_LASTMEM2STATEENTERED_MASK;
+               break;
+       case 2:
+               m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
+               break;
+       case 3:
+               m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
+               break;
+       default:
+               WARN_ON(1); /* should never happen */
+               return -EEXIST;
+       }
+
+       return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+                                       OMAP3430_PM_PREPWSTST, m);
+}
+
+/**
+ * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
+ * @pwrdm: struct powerdomain * to clear
+ *
+ * Clear the powerdomain's previous power state register.  Clears the
+ * entire register, including logic and memory bank previous power states.
+ * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
+ * success.
+ */
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       /*
+        * XXX should get the powerdomain's current state here;
+        * warn & fail if it is not ON.
+        */
+
+       pr_debug("powerdomain: clearing previous power state reg for %s\n",
+                pwrdm->name);
+
+       prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
+
+       return 0;
+}
+
+/**
+ * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
+ * @pwrdm: struct powerdomain *
+ *
+ * Enable automatic context save-and-restore upon power state change
+ * for some devices in a powerdomain.  Warning: this only affects a
+ * subset of devices in a powerdomain; check the TRM closely.  Returns
+ * -EINVAL if the powerdomain pointer is null or if the powerdomain
+ * does not support automatic save-and-restore, or returns 0 upon
+ * success.
+ */
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+               return -EINVAL;
+
+       pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
+                pwrdm->name);
+
+       prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+                            pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       return 0;
+}
+
+/**
+ * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
+ * @pwrdm: struct powerdomain *
+ *
+ * Disable automatic context save-and-restore upon power state change
+ * for some devices in a powerdomain.  Warning: this only affects a
+ * subset of devices in a powerdomain; check the TRM closely.  Returns
+ * -EINVAL if the powerdomain pointer is null or if the powerdomain
+ * does not support automatic save-and-restore, or returns 0 upon
+ * success.
+ */
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+               return -EINVAL;
+
+       pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
+                pwrdm->name);
+
+       prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
+                            pwrdm->prcm_offs, PM_PWSTCTRL);
+
+       return 0;
+}
+
+/**
+ * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
+ * @pwrdm: struct powerdomain *
+ *
+ * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore
+ * for some devices, or 0 if it does not.
+ */
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
+{
+       return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
+}
+
+/**
+ * pwrdm_wait_transition - wait for powerdomain power transition to finish
+ * @pwrdm: struct powerdomain * to wait for
+ *
+ * If the powerdomain pwrdm is in the process of a state transition,
+ * spin until it completes the power transition, or until an iteration
+ * bailout value is reached. Returns -EINVAL if the powerdomain
+ * pointer is null, -EAGAIN if the bailout value was reached, or
+ * returns 0 upon success.
+ */
+int pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+       u32 c = 0;
+
+       if (!pwrdm)
+               return -EINVAL;
+
+       /*
+        * REVISIT: pwrdm_wait_transition() may be better implemented
+        * via a callback and a periodic timer check -- how long do we expect
+        * powerdomain transitions to take?
+        */
+
+       /* XXX Is this udelay() value meaningful? */
+       while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
+               OMAP_INTRANSITION) &&
+              (c++ < PWRDM_TRANSITION_BAILOUT))
+               udelay(1);
+
+       if (c >= PWRDM_TRANSITION_BAILOUT) {
+               printk(KERN_ERR "powerdomain: waited too long for "
+                      "powerdomain %s to complete transition\n", pwrdm->name);
+               return -EAGAIN;
+       }
+
+       pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+       return 0;
+}
+
+
diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains.h
new file mode 100644 (file)
index 0000000..1e151fa
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * OMAP2/3 common powerdomain definitions
+ *
+ * Copyright (C) 2007-8 Texas Instruments, Inc.
+ * Copyright (C) 2007-8 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Debugging and integration fixes by Jouni Högander
+ *
+ * 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS
+#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS
+
+/*
+ * This file contains all of the powerdomains that have some element
+ * of software control for the OMAP24xx and OMAP34XX chips.
+ *
+ * A few notes:
+ *
+ * This is not an exhaustive listing of powerdomains on the chips; only
+ * powerdomains that can be controlled in software.
+ *
+ * A useful validation rule for struct powerdomain:
+ * Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array
+ * must have a dep_bit assigned.  So wkdep_srcs/sleepdep_srcs are really
+ * just software-controllable dependencies.  Non-software-controllable
+ * dependencies do exist, but they are not encoded below (yet).
+ *
+ * 24xx does not support programmable sleep dependencies (SLEEPDEP)
+ *
+ */
+
+/*
+ * The names for the DSP/IVA2 powerdomains are confusing.
+ *
+ * Most OMAP chips have an on-board DSP.
+ *
+ * On the 2420, this is a 'C55 DSP called, simply, the DSP.  Its
+ * powerdomain is called the "DSP power domain."  On the 2430, the
+ * on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1.  Its
+ * powerdomain is still called the "DSP power domain." On the 3430,
+ * the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but
+ * its powerdomain is now called the "IVA2 power domain."
+ *
+ * The 2420 also has something called the IVA, which is a separate ARM
+ * core, and has nothing to do with the DSP/IVA2.
+ *
+ * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM
+ * address offset is different between the C55 and C64 DSPs.
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}.  The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ */
+
+/*
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+#include <mach/powerdomain.h>
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "cm.h"
+
+/* OMAP2/3-common powerdomains and wakeup dependencies */
+
+/*
+ * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
+ * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
+ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
+ */
+static struct pwrdm_dep gfx_sgx_wkdeps[] = {
+       {
+               .pwrdm_name = "core_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "iva2_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+                                           CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+                                           CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+/*
+ * 3430: CM_SLEEPDEP_CAM: MPU
+ * 3430ES1: CM_SLEEPDEP_GFX: MPU
+ * 3430ES2: CM_SLEEPDEP_SGX: MPU
+ */
+static struct pwrdm_dep cam_gfx_sleepdeps[] = {
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+
+#include "powerdomains24xx.h"
+#include "powerdomains34xx.h"
+
+
+/*
+ * OMAP2/3 common powerdomains
+ */
+
+/*
+ * The GFX powerdomain is not present on 3430ES2, but currently we do not
+ * have a macro to filter it out at compile-time.
+ */
+static struct powerdomain gfx_pwrdm = {
+       .name             = "gfx_pwrdm",
+       .prcm_offs        = GFX_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+                                          CHIP_IS_OMAP3430ES1),
+       .wkdep_srcs       = gfx_sgx_wkdeps,
+       .sleepdep_srcs    = cam_gfx_sleepdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+static struct powerdomain wkup_pwrdm = {
+       .name           = "wkup_pwrdm",
+       .prcm_offs      = WKUP_MOD,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+       .dep_bit        = OMAP_EN_WKUP_SHIFT,
+};
+
+
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap[] __initdata = {
+
+       &gfx_pwrdm,
+       &wkup_pwrdm,
+
+#ifdef CONFIG_ARCH_OMAP24XX
+       &dsp_pwrdm,
+       &mpu_24xx_pwrdm,
+       &core_24xx_pwrdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+       &mdm_pwrdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+       &iva2_pwrdm,
+       &mpu_34xx_pwrdm,
+       &neon_pwrdm,
+       &core_34xx_pwrdm,
+       &cam_pwrdm,
+       &dss_pwrdm,
+       &per_pwrdm,
+       &emu_pwrdm,
+       &sgx_pwrdm,
+       &usbhost_pwrdm,
+#endif
+
+       NULL
+};
+
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomains24xx.h b/arch/arm/mach-omap2/powerdomains24xx.h
new file mode 100644 (file)
index 0000000..9f08dc3
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * OMAP24XX powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Debugging and integration fixes by Jouni Högander
+ *
+ * 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX
+#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX
+
+/*
+ * N.B. If powerdomains are added or removed from this file, update
+ * the array in mach-omap2/powerdomains.h.
+ */
+
+#include <mach/powerdomain.h>
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/* 24XX powerdomains and dependencies */
+
+#ifdef CONFIG_ARCH_OMAP24XX
+
+
+/* Wakeup dependency source arrays */
+
+/*
+ * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP
+ * 2430 PM_WKDEP_MDM: same as above
+ */
+static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = {
+       {
+               .pwrdm_name = "core_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       { NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
+ * 2430 adds MDM
+ */
+static struct pwrdm_dep mpu_24xx_wkdeps[] = {
+       {
+               .pwrdm_name = "core_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "dsp_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "mdm_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+       },
+       { NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
+ * 2430 adds MDM
+ */
+static struct pwrdm_dep core_24xx_wkdeps[] = {
+       {
+               .pwrdm_name = "dsp_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "gfx_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+       },
+       {
+               .pwrdm_name = "mdm_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+       },
+       { NULL },
+};
+
+
+/* Powerdomains */
+
+static struct powerdomain dsp_pwrdm = {
+       .name             = "dsp_pwrdm",
+       .prcm_offs        = OMAP24XX_DSP_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+       .dep_bit          = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+       .wkdep_srcs       = dsp_mdm_24xx_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET,
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,
+       },
+};
+
+static struct powerdomain mpu_24xx_pwrdm = {
+       .name             = "mpu_pwrdm",
+       .prcm_offs        = MPU_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+       .dep_bit          = OMAP24XX_EN_MPU_SHIFT,
+       .wkdep_srcs       = mpu_24xx_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRSTS_OFF_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET,
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,
+       },
+};
+
+static struct powerdomain core_24xx_pwrdm = {
+       .name             = "core_pwrdm",
+       .prcm_offs        = CORE_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+       .wkdep_srcs       = core_24xx_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .dep_bit          = OMAP24XX_EN_CORE_SHIFT,
+       .banks            = 3,
+       .pwrsts_mem_ret   = {
+               [0] = PWRSTS_OFF_RET,    /* MEM1RETSTATE */
+               [1] = PWRSTS_OFF_RET,    /* MEM2RETSTATE */
+               [2] = PWRSTS_OFF_RET,    /* MEM3RETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+               [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+               [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
+       },
+};
+
+#endif    /* CONFIG_ARCH_OMAP24XX */
+
+
+
+/*
+ * 2430-specific powerdomains
+ */
+
+#ifdef CONFIG_ARCH_OMAP2430
+
+/* XXX 2430 KILLDOMAINWKUP bit?  No current users apparently */
+
+/* Another case of bit name collisions between several registers: EN_MDM */
+static struct powerdomain mdm_pwrdm = {
+       .name             = "mdm_pwrdm",
+       .prcm_offs        = OMAP2430_MDM_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+       .dep_bit          = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
+       .wkdep_srcs       = dsp_mdm_24xx_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+#endif     /* CONFIG_ARCH_OMAP2430 */
+
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains34xx.h
new file mode 100644 (file)
index 0000000..f573f71
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * OMAP34XX powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Debugging and integration fixes by Jouni Högander
+ *
+ * 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX
+#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX
+
+/*
+ * N.B. If powerdomains are added or removed from this file, update
+ * the array in mach-omap2/powerdomains.h.
+ */
+
+#include <mach/powerdomain.h>
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * 34XX-specific powerdomains, dependencies
+ */
+
+#ifdef CONFIG_ARCH_OMAP34XX
+
+/*
+ * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP
+ * (USBHOST is ES2 only)
+ */
+static struct pwrdm_dep per_usbhost_wkdeps[] = {
+       {
+               .pwrdm_name = "core_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "iva2_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+/*
+ * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER
+ */
+static struct pwrdm_dep mpu_34xx_wkdeps[] = {
+       {
+               .pwrdm_name = "core_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "iva2_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "dss_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "per_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+/*
+ * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER
+ */
+static struct pwrdm_dep iva2_wkdeps[] = {
+       {
+               .pwrdm_name = "core_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "dss_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "per_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+
+/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */
+static struct pwrdm_dep cam_dss_wkdeps[] = {
+       {
+               .pwrdm_name = "iva2_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "wkup_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+/* 3430: PM_WKDEP_NEON: MPU */
+static struct pwrdm_dep neon_wkdeps[] = {
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+
+/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */
+
+/*
+ * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA
+ * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA
+ */
+static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = {
+       {
+               .pwrdm_name = "mpu_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       {
+               .pwrdm_name = "iva2_pwrdm",
+               .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       },
+       { NULL },
+};
+
+
+/*
+ * Powerdomains
+ */
+
+static struct powerdomain iva2_pwrdm = {
+       .name             = "iva2_pwrdm",
+       .prcm_offs        = OMAP3430_IVA2_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .dep_bit          = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
+       .wkdep_srcs       = iva2_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRSTS_OFF_RET,
+       .banks            = 4,
+       .pwrsts_mem_ret   = {
+               [0] = PWRSTS_OFF_RET,
+               [1] = PWRSTS_OFF_RET,
+               [2] = PWRSTS_OFF_RET,
+               [3] = PWRSTS_OFF_RET,
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,
+               [1] = PWRDM_POWER_ON,
+               [2] = PWRSTS_OFF_ON,
+               [3] = PWRDM_POWER_ON,
+       },
+};
+
+static struct powerdomain mpu_34xx_pwrdm = {
+       .name             = "mpu_pwrdm",
+       .prcm_offs        = MPU_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .dep_bit          = OMAP3430_EN_MPU_SHIFT,
+       .wkdep_srcs       = mpu_34xx_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRSTS_OFF_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRSTS_OFF_RET,
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRSTS_OFF_ON,
+       },
+};
+
+/* No wkdeps or sleepdeps for 34xx core apparently */
+static struct powerdomain core_34xx_pwrdm = {
+       .name             = "core_pwrdm",
+       .prcm_offs        = CORE_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .dep_bit          = OMAP3430_EN_CORE_SHIFT,
+       .banks            = 2,
+       .pwrsts_mem_ret   = {
+               [0] = PWRSTS_OFF_RET,    /* MEM1RETSTATE */
+               [1] = PWRSTS_OFF_RET,    /* MEM2RETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+               [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+       },
+};
+
+/* Another case of bit name collisions between several registers: EN_DSS */
+static struct powerdomain dss_pwrdm = {
+       .name             = "dss_pwrdm",
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .prcm_offs        = OMAP3430_DSS_MOD,
+       .dep_bit          = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+       .wkdep_srcs       = cam_dss_wkdeps,
+       .sleepdep_srcs    = dss_per_usbhost_sleepdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+static struct powerdomain sgx_pwrdm = {
+       .name             = "sgx_pwrdm",
+       .prcm_offs        = OMAP3430ES2_SGX_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+       .wkdep_srcs       = gfx_sgx_wkdeps,
+       .sleepdep_srcs    = cam_gfx_sleepdeps,
+       /* XXX This is accurate for 3430 SGX, but what about GFX? */
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+static struct powerdomain cam_pwrdm = {
+       .name             = "cam_pwrdm",
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .prcm_offs        = OMAP3430_CAM_MOD,
+       .wkdep_srcs       = cam_dss_wkdeps,
+       .sleepdep_srcs    = cam_gfx_sleepdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+static struct powerdomain per_pwrdm = {
+       .name             = "per_pwrdm",
+       .prcm_offs        = OMAP3430_PER_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .dep_bit          = OMAP3430_EN_PER_SHIFT,
+       .wkdep_srcs       = per_usbhost_wkdeps,
+       .sleepdep_srcs    = dss_per_usbhost_sleepdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRSTS_OFF_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+static struct powerdomain emu_pwrdm = {
+       .name           = "emu_pwrdm",
+       .prcm_offs      = OMAP3430_EMU_MOD,
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain neon_pwrdm = {
+       .name             = "neon_pwrdm",
+       .prcm_offs        = OMAP3430_NEON_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .wkdep_srcs       = neon_wkdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+};
+
+static struct powerdomain usbhost_pwrdm = {
+       .name             = "usbhost_pwrdm",
+       .prcm_offs        = OMAP3430ES2_USBHOST_MOD,
+       .omap_chip        = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+       .wkdep_srcs       = per_usbhost_wkdeps,
+       .sleepdep_srcs    = dss_per_usbhost_sleepdeps,
+       .pwrsts           = PWRSTS_OFF_RET_ON,
+       .pwrsts_logic_ret = PWRDM_POWER_RET,
+       .banks            = 1,
+       .pwrsts_mem_ret   = {
+               [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+       },
+       .pwrsts_mem_on    = {
+               [0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+       },
+};
+
+#endif    /* CONFIG_ARCH_OMAP34XX */
+
+
+#endif
index 54c32f482131819666dc81c79a2b5661ae43d515..4a32822ff3fca38834ca4c267c85fa6a5334ce28 100644 (file)
 #define OMAP3430_ST_GPT2                               (1 << 3)
 
 /* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */
-#define OMAP3430_EN_CORE                               (1 << 0)
+#define OMAP3430_EN_CORE_SHIFT                         0
+#define OMAP3430_EN_CORE_MASK                          (1 << 0)
 
 #endif
 
index c6d17a3378ec3035c683920136f49f3395053829..4002051c20b98457bdc12142e8d328d33fedc4a4 100644 (file)
 #define OMAP24XX_WKUP1_EN                              (1 << 0)
 
 /* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */
-#define OMAP24XX_EN_MPU                                        (1 << 1)
-#define OMAP24XX_EN_CORE                               (1 << 0)
+#define OMAP24XX_EN_MPU_SHIFT                          1
+#define OMAP24XX_EN_MPU_MASK                           (1 << 1)
+#define OMAP24XX_EN_CORE_SHIFT                                 0
+#define OMAP24XX_EN_CORE_MASK                          (1 << 0)
 
 /*
  * PM_PWSTCTRL_MPU, PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM
 /* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */
 
 /* PM_WKDEP_MPU specific bits */
-#define OMAP2430_PM_WKDEP_MPU_EN_MDM                   (1 << 5)
-#define OMAP24XX_PM_WKDEP_MPU_EN_DSP                   (1 << 2)
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT             5
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_MASK              (1 << 5)
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT             2
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_MASK              (1 << 2)
 
 /* PM_EVGENCTRL_MPU specific bits */
 
index b4686bc345ca661bbe58c07d7d6ac4469f9b427c..5b5ecfe6c99916847b88b50db7235f3b8c51fedc 100644 (file)
@@ -68,7 +68,8 @@
 #define OMAP3430_VPINIDLE                              (1 << 0)
 
 /* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */
-#define OMAP3430_EN_PER                                        (1 << 7)
+#define OMAP3430_EN_PER_SHIFT                          7
+#define OMAP3430_EN_PER_MASK                           (1 << 7)
 
 /* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */
 #define OMAP3430_MEMORYCHANGE                          (1 << 3)
@@ -77,7 +78,7 @@
 #define OMAP3430_LOGICSTATEST                          (1 << 2)
 
 /* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */
-#define OMAP3430_LASTLOGICSTATEENTERED                         (1 << 2)
+#define OMAP3430_LASTLOGICSTATEENTERED                 (1 << 2)
 
 /*
  * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE,
 #define OMAP3430_EMULATION_MPU_RST                     (1 << 11)
 
 /* PM_WKDEP_MPU specific bits */
-#define OMAP3430_PM_WKDEP_MPU_EN_DSS                   (1 << 5)
-#define OMAP3430_PM_WKDEP_MPU_EN_IVA2                  (1 << 2)
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT             5
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK              (1 << 5)
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT            2
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK             (1 << 2)
 
 /* PM_EVGENCTRL_MPU */
 #define OMAP3430_OFFLOADMODE_SHIFT                     3
index bbf41fc8e9a9102cd70003b59fb7c85615f4339e..e4dc4b17881d2e9cbc198aefb7bf148ac4e50688 100644 (file)
@@ -18,7 +18,7 @@
 
 #ifndef __ASSEMBLER__
 #define OMAP_PRM_REGADDR(module, reg)                                  \
-       (void __iomem *)IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg))
+                       IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg))
 #else
 #define OMAP2420_PRM_REGADDR(module, reg)                              \
                        IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
@@ -305,7 +305,8 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
  * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM,
  *      PM_WKDEP_PER
  */
-#define OMAP_EN_WKUP                                   (1 << 4)
+#define OMAP_EN_WKUP_SHIFT                             4
+#define OMAP_EN_WKUP_MASK                              (1 << 4)
 
 /*
  * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
index 7d9444adc5df6c94deb0189cb35fbba2d74d9512..4dcf39c285b94bac5e1e6292469299c633fcd0bf 100644 (file)
@@ -3,7 +3,7 @@
  *
  * OMAP2 serial support.
  *
- * Copyright (C) 2005 Nokia Corporation
+ * Copyright (C) 2005-2008 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
  *
  * Based off of arch/arm/mach-omap/omap1/serial.c
 #include <mach/common.h>
 #include <mach/board.h>
 
-static struct clk * uart1_ick = NULL;
-static struct clk * uart1_fck = NULL;
-static struct clk * uart2_ick = NULL;
-static struct clk * uart2_fck = NULL;
-static struct clk * uart3_ick = NULL;
-static struct clk * uart3_fck = NULL;
+static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
+static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
 
 static struct plat_serial8250_port serial_platform_data[] = {
        {
-               .membase        = (char *)IO_ADDRESS(OMAP_UART1_BASE),
-               .mapbase        = (unsigned long)OMAP_UART1_BASE,
+               .membase        = IO_ADDRESS(OMAP_UART1_BASE),
+               .mapbase        = OMAP_UART1_BASE,
                .irq            = 72,
                .flags          = UPF_BOOT_AUTOCONF,
                .iotype         = UPIO_MEM,
                .regshift       = 2,
-               .uartclk        = OMAP16XX_BASE_BAUD * 16,
+               .uartclk        = OMAP24XX_BASE_BAUD * 16,
        }, {
-               .membase        = (char *)IO_ADDRESS(OMAP_UART2_BASE),
-               .mapbase        = (unsigned long)OMAP_UART2_BASE,
+               .membase        = IO_ADDRESS(OMAP_UART2_BASE),
+               .mapbase        = OMAP_UART2_BASE,
                .irq            = 73,
                .flags          = UPF_BOOT_AUTOCONF,
                .iotype         = UPIO_MEM,
                .regshift       = 2,
-               .uartclk        = OMAP16XX_BASE_BAUD * 16,
+               .uartclk        = OMAP24XX_BASE_BAUD * 16,
        }, {
-               .membase        = (char *)IO_ADDRESS(OMAP_UART3_BASE),
-               .mapbase        = (unsigned long)OMAP_UART3_BASE,
+               .membase        = IO_ADDRESS(OMAP_UART3_BASE),
+               .mapbase        = OMAP_UART3_BASE,
                .irq            = 74,
                .flags          = UPF_BOOT_AUTOCONF,
                .iotype         = UPIO_MEM,
                .regshift       = 2,
-               .uartclk        = OMAP16XX_BASE_BAUD * 16,
+               .uartclk        = OMAP24XX_BASE_BAUD * 16,
        }, {
                .flags          = 0
        }
@@ -70,7 +66,7 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
                                    int value)
 {
        offset <<= p->regshift;
-       __raw_writeb(value, (unsigned long)(p->membase + offset));
+       __raw_writeb(value, p->membase + offset);
 }
 
 /*
@@ -86,10 +82,27 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
        serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
 }
 
-void __init omap_serial_init()
+void omap_serial_enable_clocks(int enable)
+{
+       int i;
+       for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+               if (uart_ick[i] && uart_fck[i]) {
+                       if (enable) {
+                               clk_enable(uart_ick[i]);
+                               clk_enable(uart_fck[i]);
+                       } else {
+                               clk_disable(uart_ick[i]);
+                               clk_disable(uart_fck[i]);
+                       }
+               }
+       }
+}
+
+void __init omap_serial_init(void)
 {
        int i;
        const struct omap_uart_config *info;
+       char name[16];
 
        /*
         * Make sure the serial ports are muxed on at this point.
@@ -97,8 +110,7 @@ void __init omap_serial_init()
         * if not needed.
         */
 
-       info = omap_get_config(OMAP_TAG_UART,
-                              struct omap_uart_config);
+       info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
 
        if (info == NULL)
                return;
@@ -107,58 +119,26 @@ void __init omap_serial_init()
                struct plat_serial8250_port *p = serial_platform_data + i;
 
                if (!(info->enabled_uarts & (1 << i))) {
-                       p->membase = 0;
+                       p->membase = NULL;
                        p->mapbase = 0;
                        continue;
                }
 
-               switch (i) {
-               case 0:
-                       uart1_ick = clk_get(NULL, "uart1_ick");
-                       if (IS_ERR(uart1_ick))
-                               printk("Could not get uart1_ick\n");
-                       else {
-                               clk_enable(uart1_ick);
-                       }
-
-                       uart1_fck = clk_get(NULL, "uart1_fck");
-                       if (IS_ERR(uart1_fck))
-                               printk("Could not get uart1_fck\n");
-                       else {
-                               clk_enable(uart1_fck);
-                       }
-                       break;
-               case 1:
-                       uart2_ick = clk_get(NULL, "uart2_ick");
-                       if (IS_ERR(uart2_ick))
-                               printk("Could not get uart2_ick\n");
-                       else {
-                               clk_enable(uart2_ick);
-                       }
-
-                       uart2_fck = clk_get(NULL, "uart2_fck");
-                       if (IS_ERR(uart2_fck))
-                               printk("Could not get uart2_fck\n");
-                       else {
-                               clk_enable(uart2_fck);
-                       }
-                       break;
-               case 2:
-                       uart3_ick = clk_get(NULL, "uart3_ick");
-                       if (IS_ERR(uart3_ick))
-                               printk("Could not get uart3_ick\n");
-                       else {
-                               clk_enable(uart3_ick);
-                       }
-
-                       uart3_fck = clk_get(NULL, "uart3_fck");
-                       if (IS_ERR(uart3_fck))
-                               printk("Could not get uart3_fck\n");
-                       else {
-                               clk_enable(uart3_fck);
-                       }
-                       break;
-               }
+               sprintf(name, "uart%d_ick", i+1);
+               uart_ick[i] = clk_get(NULL, name);
+               if (IS_ERR(uart_ick[i])) {
+                       printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
+                       uart_ick[i] = NULL;
+               } else
+                       clk_enable(uart_ick[i]);
+
+               sprintf(name, "uart%d_fck", i+1);
+               uart_fck[i] = clk_get(NULL, name);
+               if (IS_ERR(uart_fck[i])) {
+                       printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
+                       uart_fck[i] = NULL;
+               } else
+                       clk_enable(uart_fck[i]);
 
                omap_serial_reset(p);
        }
similarity index 85%
rename from arch/arm/mach-omap2/sleep.S
rename to arch/arm/mach-omap2/sleep24xx.S
index 87a706fd5f8214f13fb1c9894f9f344161b6a3ed..43336b93b21c0398494c19a925c88f24a37c709a 100644 (file)
@@ -5,6 +5,10 @@
  * Texas Instruments, <www.ti.com>
  * Richard Woodruff <r-woodruff2@ti.com>
  *
+ * (C) Copyright 2006 Nokia Corporation
+ * Fixed idle loop sleep
+ * Igor Stoppa <igor.stoppa@nokia.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
@@ -26,6 +30,8 @@
 #include <mach/io.h>
 #include <mach/pm.h>
 
+#include <mach/omap24xx.h>
+
 #include "sdrc.h"
 
 /* First address of reserved address space?  apparently valid for OMAP2 & 3 */
@@ -52,15 +58,14 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
        .word   . - omap24xx_idle_loop_suspend
 
 /*
- * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing
+ * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing
  * SDRC shutdown then ARM shutdown.  Upon wake MPU is back on so just restore
  * SDRC.
  *
  * Input:
  * R0 :        DLL ctrl value pre-Sleep
- * R1 : Processor+Revision
- *     2420: 0x21 = 242xES1, 0x26 = 242xES2.2
- *     2430: 0x31 = 2430ES1, 0x32 = 2430ES2
+ * R1 : SDRC_DLLA_CTRL
+ * R2 : SDRC_POWER
  *
  * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
  * when we get called, but the DLL probably isn't.  We will wait a bit more in
@@ -80,15 +85,14 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
  */
 ENTRY(omap24xx_cpu_suspend)
        stmfd   sp!, {r0 - r12, lr}     @ save registers on stack
-       mov     r3, #0x0                @ clear for mrc call
+       mov     r3, #0x0                @ clear for mcr call
        mcr     p15, 0, r3, c7, c10, 4  @ memory barrier, hope SDR/DDR finished
        nop
        nop
-       ldr     r3, A_SDRC_POWER        @ addr of sdrc power
-       ldr     r4, [r3]                @ value of sdrc power
+       ldr     r4, [r2]                @ read SDRC_POWER
        orr     r4, r4, #0x40           @ enable self refresh on idle req
        mov     r5, #0x2000             @ set delay (DPLL relock + DLL relock)
-       str     r4, [r3]                @ make it so
+       str     r4, [r2]                @ make it so
        mov     r2, #0
        nop
        mcr     p15, 0, r2, c7, c0, 4   @ wait for interrupt
@@ -97,14 +101,13 @@ loop:
        subs    r5, r5, #0x1            @ awake, wait just a bit
        bne     loop
 
-       /* The DPLL has on before we take the DDR out of self refresh */
+       /* The DPLL has to be on before we take the DDR out of self refresh */
        bic     r4, r4, #0x40           @ now clear self refresh bit.
-       str     r4, [r3]                @ put vlaue back.
+       str     r4, [r2]                @ write to SDRC_POWER
        ldr     r4, A_SDRC0             @ make a clock happen
-       ldr     r4, [r4]
+       ldr     r4, [r4]                @ read A_SDRC0
        nop                             @ start auto refresh only after clk ok
        movs    r0, r0                  @ see if DDR or SDR
-       ldrne   r1, A_SDRC_DLLA_CTRL_S  @ get addr of DLL ctrl
        strne   r0, [r1]                @ rewrite DLLA to force DLL reload
        addne   r1, r1, #0x8            @ move to DLLB
        strne   r0, [r1]                @ rewrite DLLB to force DLL reload
@@ -116,13 +119,8 @@ loop2:
        /* resume*/
        ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
 
-A_SDRC_POWER:
-       .word OMAP242X_SDRC_REGADDR(SDRC_POWER)
 A_SDRC0:
        .word A_SDRC0_V
-A_SDRC_DLLA_CTRL_S:
-       .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
 
 ENTRY(omap24xx_cpu_suspend_sz)
        .word   . - omap24xx_cpu_suspend
-
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
new file mode 100644 (file)
index 0000000..2c71461
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * linux/arch/arm/mach-omap3/sram.S
+ *
+ * Omap3 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2007
+ * Texas Instruments Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.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.
+ *
+ * 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 <mach/hardware.h>
+
+#include <mach/io.h>
+
+#include "sdrc.h"
+#include "cm.h"
+
+       .text
+
+/*
+ * Change frequency of core dpll
+ * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
+ */
+ENTRY(omap3_sram_configure_core_dpll)
+       stmfd   sp!, {r1-r12, lr}       @ store regs to stack
+       cmp     r3, #0x2
+       blne    configure_sdrc
+       cmp     r3, #0x2
+       blne    lock_dll
+       cmp     r3, #0x1
+       blne    unlock_dll
+       bl      sdram_in_selfrefresh    @ put the SDRAM in self refresh
+       bl      configure_core_dpll
+       bl      enable_sdrc
+       cmp     r3, #0x1
+       blne    wait_dll_unlock
+       cmp     r3, #0x2
+       blne    wait_dll_lock
+       cmp     r3, #0x1
+       blne    configure_sdrc
+       mov     r0, #0                  @ return value
+       ldmfd   sp!, {r1-r12, pc}       @ restore regs and return
+unlock_dll:
+       ldr     r4, omap3_sdrc_dlla_ctrl
+       ldr     r5, [r4]
+       orr     r5, r5, #0x4
+       str     r5, [r4]
+       bx      lr
+lock_dll:
+       ldr     r4, omap3_sdrc_dlla_ctrl
+       ldr     r5, [r4]
+       bic     r5, r5, #0x4
+       str     r5, [r4]
+       bx      lr
+sdram_in_selfrefresh:
+       mov     r5, #0x0                @ Move 0 to R5
+       mcr     p15, 0, r5, c7, c10, 5  @ memory barrier
+       ldr     r4, omap3_sdrc_power    @ read the SDRC_POWER register
+       ldr     r5, [r4]                @ read the contents of SDRC_POWER
+       orr     r5, r5, #0x40           @ enable self refresh on idle req
+       str     r5, [r4]                @ write back to SDRC_POWER register
+       ldr     r4, omap3_cm_iclken1_core       @ read the CM_ICLKEN1_CORE reg
+       ldr     r5, [r4]
+       bic     r5, r5, #0x2            @ disable iclk bit for SRDC
+       str     r5, [r4]
+wait_sdrc_idle:
+       ldr     r4, omap3_cm_idlest1_core
+       ldr     r5, [r4]
+       and     r5, r5, #0x2            @ check for SDRC idle
+       cmp     r5, #2
+       bne     wait_sdrc_idle
+       bx      lr
+configure_core_dpll:
+       ldr     r4, omap3_cm_clksel1_pll
+       ldr     r5, [r4]
+       ldr     r6, core_m2_mask_val    @ modify m2 for core dpll
+       and     r5, r5, r6
+       orr     r5, r5, r3, lsl #0x1B   @ r3 contains the M2 val
+       str     r5, [r4]
+       mov     r5, #0x800              @ wait for the clock to stabilise
+       cmp     r3, #2
+       bne     wait_clk_stable
+       bx      lr
+wait_clk_stable:
+       subs    r5, r5, #1
+       bne     wait_clk_stable
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       bx      lr
+enable_sdrc:
+       ldr     r4, omap3_cm_iclken1_core
+       ldr     r5, [r4]
+       orr     r5, r5, #0x2            @ enable iclk bit for SDRC
+       str     r5, [r4]
+wait_sdrc_idle1:
+       ldr     r4, omap3_cm_idlest1_core
+       ldr     r5, [r4]
+       and     r5, r5, #0x2
+       cmp     r5, #0
+       bne     wait_sdrc_idle1
+       ldr     r4, omap3_sdrc_power
+       ldr     r5, [r4]
+       bic     r5, r5, #0x40
+       str     r5, [r4]
+       bx      lr
+wait_dll_lock:
+       ldr     r4, omap3_sdrc_dlla_status
+       ldr     r5, [r4]
+       and     r5, r5, #0x4
+       cmp     r5, #0x4
+       bne     wait_dll_lock
+       bx      lr
+wait_dll_unlock:
+       ldr     r4, omap3_sdrc_dlla_status
+       ldr     r5, [r4]
+       and     r5, r5, #0x4
+       cmp     r5, #0x0
+       bne     wait_dll_unlock
+       bx      lr
+configure_sdrc:
+       ldr     r4, omap3_sdrc_rfr_ctrl
+       str     r0, [r4]
+       ldr     r4, omap3_sdrc_actim_ctrla
+       str     r1, [r4]
+       ldr     r4, omap3_sdrc_actim_ctrlb
+       str     r2, [r4]
+       bx      lr
+
+omap3_sdrc_power:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
+omap3_cm_clksel1_pll:
+       .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap3_cm_idlest1_core:
+       .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST)
+omap3_cm_iclken1_core:
+       .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1)
+omap3_sdrc_rfr_ctrl:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap3_sdrc_actim_ctrla:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
+omap3_sdrc_actim_ctrlb:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
+omap3_sdrc_dlla_status:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
+omap3_sdrc_dlla_ctrl:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
+core_m2_mask_val:
+       .word 0x07FFFFFF
+
+ENTRY(omap3_sram_configure_core_dpll_sz)
+       .word   . - omap3_sram_configure_core_dpll
index a82dad1a8cc86c76cef9fa50619695903b03d138..df83b97f303fd989c0df1795cea48c98ea82ecf6 100644 (file)
@@ -162,7 +162,7 @@ static void __init cmx270_init_rtc(void)
        platform_device_register(&cmx270_rtc_device);
 }
 #else
-static inline void cmx2xx_init_rtc(void) {}
+static inline void cmx270_init_rtc(void) {}
 #endif
 
 /* 2700G graphics */
index d82528e74bd0e3d27359169246da5e14e56828c9..1f272ea83f36e63c824822acc98ec388018d71ae 100644 (file)
@@ -335,9 +335,6 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
                pxa27x_guess_max_freq();
 
        /* set default policy and cpuinfo */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-       if (cpu_is_pxa25x())
-               policy->policy = CPUFREQ_POLICY_PERFORMANCE;
        policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
        policy->cur = get_clk_frequency_khz(0);    /* current freq */
        policy->min = policy->max = policy->cur;
index 1ea0c9c0adaf5a6b2825a8d2042ed93435dc216a..968c8309ec37226247d8c2604a332c2048f4225d 100644 (file)
@@ -210,7 +210,6 @@ static __init int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
        int ret = -EINVAL;
 
        /* set default policy and cpuinfo */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        policy->cpuinfo.min_freq = 104000;
        policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
        policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
index d7632f63603c2967f2098a4df5d0792249603631..4b3120dbc049946b75f05b94b8f6479ca40ecdd9 100644 (file)
@@ -204,25 +204,54 @@ static void viper_set_core_cpu_voltage(unsigned long khz, int force)
 
 /* Interrupt handling */
 static unsigned long viper_irq_enabled_mask;
+static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
+static const int viper_isa_irq_map[] = {
+       0,              /* ISA irq #0, invalid */
+       0,              /* ISA irq #1, invalid */
+       0,              /* ISA irq #2, invalid */
+       1 << 0,         /* ISA irq #3 */
+       1 << 1,         /* ISA irq #4 */
+       1 << 2,         /* ISA irq #5 */
+       1 << 3,         /* ISA irq #6 */
+       1 << 4,         /* ISA irq #7 */
+       0,              /* ISA irq #8, invalid */
+       1 << 8,         /* ISA irq #9 */
+       1 << 5,         /* ISA irq #10 */
+       1 << 6,         /* ISA irq #11 */
+       1 << 7,         /* ISA irq #12 */
+       0,              /* ISA irq #13, invalid */
+       1 << 9,         /* ISA irq #14 */
+       1 << 10,        /* ISA irq #15 */
+};
+
+static inline int viper_irq_to_bitmask(unsigned int irq)
+{
+       return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)];
+}
+
+static inline int viper_bit_to_irq(int bit)
+{
+       return viper_isa_irqs[bit] + PXA_ISA_IRQ(0);
+}
 
 static void viper_ack_irq(unsigned int irq)
 {
-       int viper_irq = irq - PXA_ISA_IRQ(0);
+       int viper_irq = viper_irq_to_bitmask(irq);
 
-       if (viper_irq < 8)
-               VIPER_LO_IRQ_STATUS = 1 << viper_irq;
+       if (viper_irq & 0xff)
+               VIPER_LO_IRQ_STATUS = viper_irq;
        else
-               VIPER_HI_IRQ_STATUS = 1 << (viper_irq - 8);
+               VIPER_HI_IRQ_STATUS = (viper_irq >> 8);
 }
 
 static void viper_mask_irq(unsigned int irq)
 {
-       viper_irq_enabled_mask &= ~(1 << (irq - PXA_ISA_IRQ(0)));
+       viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(irq));
 }
 
 static void viper_unmask_irq(unsigned int irq)
 {
-       viper_irq_enabled_mask |= (1 << (irq - PXA_ISA_IRQ(0)));
+       viper_irq_enabled_mask |= viper_irq_to_bitmask(irq);
 }
 
 static inline unsigned long viper_irq_pending(void)
@@ -237,8 +266,12 @@ static void viper_irq_handler(unsigned int irq, struct irq_desc *desc)
 
        pending = viper_irq_pending();
        do {
+               /* we're in a chained irq handler,
+                * so ack the interrupt by hand */
+               GEDR(VIPER_CPLD_GPIO) = GPIO_bit(VIPER_CPLD_GPIO);
+
                if (likely(pending)) {
-                       irq = PXA_ISA_IRQ(0) + __ffs(pending);
+                       irq = viper_bit_to_irq(__ffs(pending));
                        generic_handle_irq(irq);
                }
                pending = viper_irq_pending();
@@ -254,15 +287,14 @@ static struct irq_chip viper_irq_chip = {
 
 static void __init viper_init_irq(void)
 {
-       const int isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
-       int irq;
+       int level;
        int isa_irq;
 
        pxa25x_init_irq();
 
        /* setup ISA IRQs */
-       for (irq = 0; irq < ARRAY_SIZE(isa_irqs); irq++) {
-               isa_irq = isa_irqs[irq];
+       for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) {
+               isa_irq = viper_bit_to_irq(level);
                set_irq_chip(isa_irq, &viper_irq_chip);
                set_irq_handler(isa_irq, handle_edge_irq);
                set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
index 75738000272be89f69c3e4fd8b6c725a97e0644f..9a37c87152b0074a0da7d47a0c2cd2f914b829df 100644 (file)
@@ -38,7 +38,7 @@
 #include <mach/bast-map.h>
 #include <mach/bast-irq.h>
 
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/irq.h>
 
 #if 0
 #include <asm/debug-ll.h>
index fef646c36b540600576e83f4e982e2983302099b..4e07943c1e29116603aef7427ec41410084949ed 100644 (file)
 
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 int s3c2410_clkcon_enable(struct clk *clk, int enable)
 {
index 8730797749e3a8ee65ea7daed665d32a828a14e3..7d914a470b6c7d228d8bf841380524b6fd65a56f 100644 (file)
 #include <asm/dma.h>
 #include <mach/dma.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/dma.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <asm/plat-s3c/regs-ac97.h>
 #include <mach/regs-mem.h>
index 682df23087ab43134dd043cda3a83dcc85da0125..4c29a89ad0770566b4969a84354af3d2e4f76b14 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
 #define S3C2410_UART1_OFF (0x4000)
 #define SHIFT_2440TXF (14-9)
@@ -99,4 +99,4 @@
 
 /* include the reset of the code which will do the work */
 
-#include <asm/plat-s3c/debug-macro.S>
+#include <plat/debug-macro.S>
index 64bf7e94a5bf0baac8a68008c9ed23bebef28a5d..23c470c2e5b13cf1420a542875c80ab07547cc4a 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef __ASM_ARCH_MAP_H
 #define __ASM_ARCH_MAP_H
 
-#include <asm/plat-s3c/map.h>
+#include <plat/map.h>
 
 #define S3C2410_ADDR(x)                S3C_ADDR(x)
 
index 921b13b4f0a055dc3c036138149e6ca14db8fc89..46d46f5b99f2817b92c43729928371f0d3a8fb08 100644 (file)
@@ -18,6 +18,7 @@ struct s3c2410_spi_info {
        unsigned int             num_cs;        /* total chipselects */
        int                      bus_num;       /* bus number to use. */
 
+       void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);
        void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
 };
 
index 708e47459ffc91f331804a63d08c32890a3cb41b..ab39491beee209328854aef56651b4e829d30171 100644 (file)
@@ -21,7 +21,7 @@
 #undef S3C2410_GPIOREG
 #define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
 
-#include <asm/plat-s3c/uncompress.h>
+#include <plat/uncompress.h>
 
 static inline int is_arm926(void)
 {
index f5c5c53e1cc18f6b3f663f41c9f5b26380360b0d..92150399563bdddabab2cd7ec3ca2da4fc2514b7 100644 (file)
@@ -25,8 +25,8 @@
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
 static int s3c2410_irq_add(struct sys_device *sysdev)
 {
index 527f88a288ec4ea094ffb4dc63e2a27e5c606b46..d061fea01900138879c776af78150e2966942db3 100644 (file)
 #include <asm/mach-types.h>
 #include <mach/fb.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 
index e4368e6e7e6c9ac6b70c735c770bb747b2f65b2b..8db9c700e3c24cbf621a2403960e6fe159ac4fb3 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/mach-types.h>
 
 //#include <asm/debug-ll.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
@@ -55,9 +55,9 @@
 
 #include <linux/serial_8250.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 #include "usb-simtec.h"
 #include "nor-simtec.h"
index 85e710f2863b37ec9a3edf21df100741f96c1f4a..98716d0108e9d670747c56b45598fb78253961b2 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
 #include <mach/fb.h>
 #include <asm/plat-s3c24xx/udc.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
 static struct map_desc h1940_iodesc[] __initdata = {
        [0] = {
index 3ece2d04934e20ce90ec6c2b4ac7bc67846e03fa..82505517846c532f32e87db5e927e0da18e541fa 100644 (file)
 #include <asm/mach/map.h>
 
 #include <asm/plat-s3c/iic.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s3c2410.h>
 #include <asm/plat-s3c24xx/udc.h>
 
 static struct map_desc n30_iodesc[] __initdata = {
index c4dfe3eabe1d87a21e0bc741284a707e0495b031..d8255cf87e446ef07f8f719d2413bf2957ab6b1a 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 static struct map_desc otom11_iodesc[] __initdata = {
   /* Device area */
index 97c13192315ba8ae60140250e7648ab8b66ef0be..661807e14e8a56f8b2c1eb304bc15543a5b05d31 100644 (file)
 
 #include <mach/regs-gpio.h>
 #include <mach/leds-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/fb.h>
 #include <asm/plat-s3c/nand.h>
 #include <asm/plat-s3c24xx/udc.h>
 #include <mach/spi.h>
 #include <mach/spi-gpio.h>
 
-#include <asm/plat-s3c24xx/common-smdk.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/common-smdk.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
 static struct map_desc qt2410_iodesc[] __initdata = {
        { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
index d49e58acb03b033eaaacaf15accb8bd75c88ee14..152527bb287290e28522c581fbff65368eab4b08 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
 
 static struct map_desc smdk2410_iodesc[] __initdata = {
   /* nothing here yet */
index cc2e79fe4f9f6a3e7abca47fccd91f8ae6c6c4cb..309dcf4c870af92c8603276d0b7f1e3ccfa83939 100644 (file)
@@ -44,9 +44,9 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/regs-serial.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 
index ed3acb05c8553253a1598ef52c50c5907cb043a7..941353af16dc85f546107e222f5a5c5bec3649a9 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/leds-gpio.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 #include "usb-simtec.h"
 #include "nor-simtec.h"
index 733f8a22777536c43339cf9cb2d3ae2b0ccf42c9..a6970f6131926cdb3550e90fec3ed72a95377cc1 100644 (file)
@@ -34,8 +34,8 @@
 #include <mach/regs-gpio.h>
 #include <mach/h1940.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
 #ifdef CONFIG_S3C2410_PM_DEBUG
 extern void pm_dbg(const char *fmt, ...);
index b1e658c917a07840171c85601a120a420bb0a941..ac79b536c4c3d5510f84e969e5cb4cfe5faecb9e 100644 (file)
 #include <asm/irq.h>
 
 #include <mach/regs-clock.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/clock.h>
+#include <plat/s3c2410.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
 
 /* Initial IO mappings */
 
index be37f221a177b529b9da67aba5a4104a6d4b474d..dd5b6388a5a555826e80eab1eae0710040d954f6 100644 (file)
@@ -32,7 +32,7 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-mem.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
        /* s3c2410_cpu_suspend
         *
index eb6fc0bfd47ecd8f1e28f7b4e49fc0d31dedcb86..6078f09b7df5d9311cc42ab7796e9b16271cb10c 100644 (file)
@@ -35,7 +35,7 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
-#include <asm/plat-s3c24xx/devs.h>
+#include <plat/devs.h>
 #include "usb-simtec.h"
 
 /* control power and monitor over-current events on various Simtec
index 5fbaac6054f8a0ce3fb9f94163308a42074f9d4a..96d9eb15424f38087ec3b2a210add4ab7ea4d842 100644 (file)
 
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 /* We currently have to assume that the system is running
  * from the XTPll input, and that all ***REFCLKs are being
index dcfff6b8b95854c173211b70d2babfb740cc75ea..ba0591e71f329aff73ae383c3549f22d17390507 100644 (file)
 #include <asm/dma.h>
 #include <mach/dma.h>
 
-#include <asm/plat-s3c24xx/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <asm/plat-s3c/regs-ac97.h>
 #include <mach/regs-mem.h>
index 41720f2c1fea8eb3d1ccb52ac181a4540c76061d..6000ca9d18156d6d0c48736e0c3e82bc1905b3a3 100644 (file)
@@ -35,9 +35,9 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-power.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/irq.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/irq.h>
+#include <plat/pm.h>
 
 #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
 #define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
index ad980a1690c261b7ea8386616418993b10faf911..b08f18c8c47a0144868763d46c44eb844b93eb6b 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <asm/plat-s3c/nand.h>
 #include <asm/plat-s3c/iic.h>
 
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 #include <asm/plat-s3c24xx/udc.h>
 
 static struct map_desc jive_iodesc[] __initdata = {
index 8f8d9117b968d0d77635da2e4a563783c001d5dc..c719b5a740a914cc2a5d75e8f9bec7d02b2fb3e5 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/mach-types.h>
 
 //#include <asm/debug-ll.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
 #include <asm/plat-s3c24xx/udc.h>
 #include <mach/fb.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
 
 static struct map_desc smdk2413_iodesc[] __initdata = {
 };
index bb9bf63b2e02d0564fffbbe2cf86a15cb52ee60f..4cfa19ad9be015947c8b9f538a29f76715c3a388 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
 
 #include <asm/plat-s3c/nand.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 
 static struct map_desc vstms_iodesc[] __initdata = {
index 9540ef752f73c2da727a7b74b096981d4b450031..217e9e4ed45f20a9d5b0c1ce678ab752f8b4f2e5 100644 (file)
 #include <mach/regs-gpio.h>
 #include <mach/regs-dsc.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
-#include <asm/plat-s3c24xx/s3c2412.h>
+#include <plat/s3c2412.h>
 
 extern void s3c2412_sleep_enter(void);
 
index 42440fc5568192e225a8a5aa46b8d7e6c260251a..313759c3da69fcc0ba4f357342f2191475a9ed4b 100644 (file)
@@ -34,7 +34,7 @@
 #include <mach/idle.h>
 
 #include <mach/regs-clock.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-power.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-gpioj.h>
 #include <asm/plat-s3c24xx/regs-spi.h>
 #include <mach/regs-s3c2412.h>
 
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/s3c2412.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/pm.h>
 
 #ifndef CONFIG_CPU_S3C2412_ONLY
 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
index 40503a65bacfffa51b5199a14eac13868f31ef9e..d1c29b2537cda76a79ff40ee45ac6c030110e8cb 100644 (file)
@@ -41,8 +41,8 @@
 
 #include <mach/regs-clock.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 /* S3C2440 extended clock support */
 
index cdd4e6e79ac0277859c37b9a051a09b127e9060c..32303f6a83219dc5f2a3b6b263610ae77121d40a 100644 (file)
 #include <asm/dma.h>
 #include <mach/dma.h>
 
-#include <asm/plat-s3c24xx/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <asm/plat-s3c/regs-ac97.h>
 #include <mach/regs-mem.h>
index 4f7d06baf0d377a7c1427820c413c6cb574dc6e0..55404427277134300c12cf81359d040faddda67a 100644 (file)
@@ -27,8 +27,8 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-dsc.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
+#include <plat/cpu.h>
+#include <plat/s3c2440.h>
 
 int s3c2440_set_dsc(unsigned int pin, unsigned int value)
 {
index 33e3ede0a2b32d3623c31ec06390b29e51c5b99c..63c5ab65727f60a2f54877c6899f8b50e6b8edb6 100644 (file)
@@ -34,9 +34,9 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
 
 /* WDT/AC97 */
 
index 19eb0e5269ac3bf7e458563a1fe92ae2decd3c02..e2beca4704847daee81d643f0870a65c81eca5f6 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
@@ -48,9 +48,9 @@
 
 #include <net/ax88796.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 #define COPYRIGHT ", (c) 2005 Simtec Electronics"
 
index f0f0cc6afcf469cc32e1a259ee01c0ac95092549..66876c6f2f1c593f643cbdd9be679a7949597a27 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
@@ -42,9 +42,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 static struct map_desc at2440evb_iodesc[] __initdata = {
        /* Nothing here */
index 49e828d1d4d852e33a425424481938e572b08975..a546307fd53d8abb2ff39d84bc2a72b401c893ea 100644 (file)
 
 //#include <asm/debug-ll.h>
 #include <mach/regs-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 static struct map_desc nexcoder_iodesc[] __initdata = {
        /* nothing here yet */
index 85144aa52c276e7449dee5266e48a4fc36170a27..2361d606abc50fdd85ddd84c7ac54473d61a9145 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
@@ -44,9 +44,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 /* onboard perihperal map */
 
index a4c690456d19a40f3ffcb72a08905f2292cb429c..4d14c7cff89214eaab3357ec5b138fa27b64b41b 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
 #include <asm/plat-s3c/nand.h>
 #include <mach/fb.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
 static struct map_desc rx3715_iodesc[] __initdata = {
        /* dump ISA space somewhere unused */
index 7ac60b869e7fde7dfe708b1972072102b9359ee6..fefeaaa4155fff74bb21d9320b38063342b54acd 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
 #include <mach/idle.h>
 #include <mach/fb.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
 
 static struct map_desc smdk2440_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */
index c81cdb330712cdb3bc16ac708fe4fba4b6b255cd..ac1f7ea5f405ff342a3b1fd550eb940e43df0486 100644 (file)
@@ -29,9 +29,9 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2440.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 static struct sys_device s3c2440_sysdev = {
        .cls            = &s3c2440_sysclass,
index 18f2ce4d7b23b7667b6748627fe0daa1cf25092a..ea1aa1f5157a7959b5080a42743a9ed2e2abe99b 100644 (file)
@@ -41,8 +41,8 @@
 
 #include <mach/regs-clock.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 /* S3C2442 extended clock support */
 
index fbf8264249da376879221f29e82b08a4138657e3..4663bdc7fff6f26bad2cf161186d805e8a8690c7 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
 
-#include <asm/plat-s3c24xx/s3c2442.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2442.h>
+#include <plat/cpu.h>
 
 static struct sys_device s3c2442_sysdev = {
        .cls            = &s3c2442_sysclass,
index 603b5ea1deab4b96b0a267a816ccfc7c89f6953a..2f60bf6b8d4395e49bc49fcc3dfc072386c17656 100644 (file)
@@ -39,9 +39,9 @@
 
 #include <mach/regs-s3c2443-clock.h>
 
-#include <asm/plat-s3c24xx/s3c2443.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 /* We currently have to assume that the system is running
  * from the XTPll input, and that all ***REFCLKs are being
index 5d9ee772659bd73ca696415d205522e6a31fac1c..f73ccb25ff9488136cbcbae50e16a1a03f5b384d 100644 (file)
 #include <asm/dma.h>
 #include <mach/dma.h>
 
-#include <asm/plat-s3c24xx/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <asm/plat-s3c/regs-ac97.h>
 #include <mach/regs-mem.h>
index e44341d7dfef91189ad960cbcc8264357879eecd..0e0d693f397449139f8fd9e790a1f4693e3f661b 100644 (file)
@@ -34,9 +34,9 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
 
 #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
 
index f0d119dc040906838fadedcc73d940e2946450da..a7fe65f3dcc16a08b0212adfd4abd373174d7435 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
 #include <mach/idle.h>
 #include <mach/fb.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
 
 static struct map_desc smdk2443_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */
index c973b68cc7358c4c01f57b18ad41bd063ae2947b..bbeddf9ddcb1a68c99835f039f10a150c66f64f2 100644 (file)
@@ -32,9 +32,9 @@
 #include <mach/regs-s3c2443-clock.h>
 #include <mach/reset.h>
 
-#include <asm/plat-s3c24xx/s3c2443.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2443.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 
 static struct map_desc s3c2443_iodesc[] __initdata = {
        IODESC_ENT(WATCHDOG),
index f7fa03478efd9e7c203c72363696e8651209499d..244d5956312cfb106cf90e39a4863ba082943ac0 100644 (file)
@@ -224,7 +224,6 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
        if (policy->cpu != 0)
                return -EINVAL;
        policy->cur = policy->min = policy->max = sa11x0_getspeed(0);
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        policy->cpuinfo.min_freq = 59000;
        policy->cpuinfo.max_freq = 287000;
        policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
index 330814d1ee2536e65dc23273ea01d225088688fe..d1193884d76d9ce4540b5d2a9d11e94e0233536b 100644 (file)
@@ -428,7 +428,7 @@ config CPU_32v6K
 # ARMv7
 config CPU_V7
        bool "Support ARM V7 processor"
-       depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
+       depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3
        select CPU_32v6K
        select CPU_32v7
        select CPU_ABRT_EV7
index b917206ee9068036f6e17570162595a16afbdf38..a94f0c44ebc8286b042f39a8de172c7d80eb4238 100644 (file)
@@ -15,6 +15,9 @@ config ARCH_OMAP1
 config ARCH_OMAP2
        bool "TI OMAP2"
 
+config ARCH_OMAP3
+       bool "TI OMAP3"
+
 endchoice
 
 comment "OMAP Feature Selections"
@@ -29,6 +32,30 @@ config OMAP_DEBUG_LEDS
        depends on OMAP_DEBUG_DEVICES
        default y if LEDS || LEDS_OMAP_DEBUG
 
+config OMAP_DEBUG_POWERDOMAIN
+       bool "Emit debug messages from powerdomain layer"
+       depends on ARCH_OMAP2 || ARCH_OMAP3
+       default n
+       help
+         Say Y here if you want to compile in powerdomain layer
+         debugging messages for OMAP2/3.   These messages can
+         provide more detail as to why some powerdomain calls
+         may be failing, and will also emit a descriptive message
+         for every powerdomain register write.  However, the
+         extra detail costs some memory.
+
+config OMAP_DEBUG_CLOCKDOMAIN
+       bool "Emit debug messages from clockdomain layer"
+       depends on ARCH_OMAP2 || ARCH_OMAP3
+       default n
+       help
+         Say Y here if you want to compile in clockdomain layer
+         debugging messages for OMAP2/3.   These messages can
+         provide more detail as to why some clockdomain calls
+         may be failing, and will also emit a descriptive message
+         for every clockdomain register write.  However, the
+         extra detail costs some memory.
+
 config OMAP_RESET_CLOCKS
        bool "Reset unused clocks during boot"
        depends on ARCH_OMAP
@@ -88,13 +115,13 @@ config OMAP_MPU_TIMER
 
 config OMAP_32K_TIMER
        bool "Use 32KHz timer"
-       depends on ARCH_OMAP16XX || ARCH_OMAP24XX
+       depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
        help
          Select this option if you want to enable the OMAP 32KHz timer.
          This timer saves power compared to the OMAP_MPU_TIMER, and has
          support for no tick during idle. The 32KHz timer provides less
          intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
-         currently only available for OMAP16XX and 24XX.
+         currently only available for OMAP16XX, 24XX and 34XX.
 
 endchoice
 
@@ -109,7 +136,7 @@ config OMAP_32K_TIMER_HZ
 
 config OMAP_DM_TIMER
        bool "Use dual-mode timer"
-       depends on ARCH_OMAP16XX || ARCH_OMAP24XX
+       depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
        help
         Select this option if you want to use OMAP Dual-Mode timers.
 
index 2c4051cc79a13f249e32d4cb6abf31841ee1c258..deaff58878a2fe7cfd1324cf2afc6653eaf7ec99 100644 (file)
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
-        usb.o fb.o
+        usb.o fb.o io.o
 obj-m :=
 obj-n :=
 obj-  :=
index 8bdf0ead0cf36ec58316a5a49bc26813a92450ae..0843b8882f9311aa38dd972537dd5f5f757e86e7 100644 (file)
@@ -248,6 +248,7 @@ static struct omap_globals *omap2_globals;
 
 static void __init __omap2_set_globals(void)
 {
+       omap2_set_globals_tap(omap2_globals);
        omap2_set_globals_memory(omap2_globals);
        omap2_set_globals_control(omap2_globals);
        omap2_set_globals_prcm(omap2_globals);
@@ -258,12 +259,13 @@ static void __init __omap2_set_globals(void)
 #if defined(CONFIG_ARCH_OMAP2420)
 
 static struct omap_globals omap242x_globals = {
-       .tap    = (__force void __iomem *)OMAP2_IO_ADDRESS(0x48014000),
-       .sdrc   = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE),
-       .sms    = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE),
-       .ctrl   = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE),
-       .prm    = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE),
-       .cm     = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CM_BASE),
+       .class  = OMAP242X_CLASS,
+       .tap    = OMAP2_IO_ADDRESS(0x48014000),
+       .sdrc   = OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE),
+       .sms    = OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE),
+       .ctrl   = OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE),
+       .prm    = OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE),
+       .cm     = OMAP2_IO_ADDRESS(OMAP2420_CM_BASE),
 };
 
 void __init omap2_set_globals_242x(void)
@@ -276,12 +278,13 @@ void __init omap2_set_globals_242x(void)
 #if defined(CONFIG_ARCH_OMAP2430)
 
 static struct omap_globals omap243x_globals = {
-       .tap    = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4900a000),
-       .sdrc   = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE),
-       .sms    = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE),
-       .ctrl   = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE),
-       .prm    = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE),
-       .cm     = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_CM_BASE),
+       .class  = OMAP243X_CLASS,
+       .tap    = OMAP2_IO_ADDRESS(0x4900a000),
+       .sdrc   = OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE),
+       .sms    = OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE),
+       .ctrl   = OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE),
+       .prm    = OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE),
+       .cm     = OMAP2_IO_ADDRESS(OMAP2430_CM_BASE),
 };
 
 void __init omap2_set_globals_243x(void)
@@ -294,12 +297,13 @@ void __init omap2_set_globals_243x(void)
 #if defined(CONFIG_ARCH_OMAP3430)
 
 static struct omap_globals omap343x_globals = {
-       .tap    = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4830A000),
-       .sdrc   = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE),
-       .sms    = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE),
-       .ctrl   = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE),
-       .prm    = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE),
-       .cm     = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_CM_BASE),
+       .class  = OMAP343X_CLASS,
+       .tap    = OMAP2_IO_ADDRESS(0x4830A000),
+       .sdrc   = OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE),
+       .sms    = OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE),
+       .ctrl   = OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE),
+       .prm    = OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE),
+       .cm     = OMAP2_IO_ADDRESS(OMAP3430_CM_BASE),
 };
 
 void __init omap2_set_globals_343x(void)
index 97187fa0ae52b529a1f51453a29d2f2577c0605a..0cb2b22388e93454a7fe78b69e465fee6a519379 100644 (file)
 #include <asm/mach/map.h>
 
 #include <mach/tc.h>
+#include <mach/control.h>
 #include <mach/board.h>
 #include <mach/mmc.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
 #include <mach/menelaus.h>
 #include <mach/mcbsp.h>
+#include <mach/dsp_common.h>
 
 #if    defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
 
-#include "../plat-omap/dsp/dsp_common.h"
-
 static struct dsp_platform_data dsp_pdata = {
        .kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list),
 };
@@ -76,7 +76,7 @@ int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev)
 {
        static DEFINE_MUTEX(dsp_pdata_lock);
 
-       mutex_init(&kdev->lock);
+       spin_lock_init(&kdev->lock);
 
        mutex_lock(&dsp_pdata_lock);
        list_add_tail(&kdev->entry, &dsp_pdata.kdev_list);
@@ -95,6 +95,10 @@ static inline void omap_init_dsp(void) { }
 
 static void omap_init_kp(void)
 {
+       /* 2430 and 34xx keypad is on TWL4030 */
+       if (cpu_is_omap2430() || cpu_is_omap34xx())
+               return;
+
        if (machine_is_omap_h2() || machine_is_omap_h3()) {
                omap_cfg_reg(F18_1610_KBC0);
                omap_cfg_reg(D20_1610_KBC1);
@@ -156,13 +160,6 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
 {
        int i;
 
-       if (size > OMAP_MAX_MCBSP_COUNT) {
-               printk(KERN_WARNING "Registered too many McBSPs platform_data."
-                       " Using maximum (%d) available.\n",
-                       OMAP_MAX_MCBSP_COUNT);
-               size = OMAP_MAX_MCBSP_COUNT;
-       }
-
        omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
                                     GFP_KERNEL);
        if (!omap_mcbsp_devices) {
@@ -530,10 +527,6 @@ static inline void omap_init_rng(void) {}
  */
 static int __init omap_init_devices(void)
 {
-/*
- * Need to enable relevant once for 2430 SDP
- */
-#ifndef CONFIG_MACH_OMAP_2430SDP
        /* please keep these calls, and their implementations above,
         * in alphabetical order so they're easier to sort through.
         */
@@ -543,7 +536,6 @@ static int __init omap_init_devices(void)
        omap_init_uwire();
        omap_init_wdt();
        omap_init_rng();
-#endif
        return 0;
 }
 arch_initcall(omap_init_devices);
index a63b644ad30574b024f4ff60146f9233b7fa17db..50f8b4ad9a0942a0e818a746dff055d17b8be139 100644 (file)
@@ -1233,7 +1233,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name,
        /* request and reserve DMA channels for the chain */
        for (i = 0; i < no_of_chans; i++) {
                err = omap_request_dma(dev_id, dev_name,
-                                       callback, 0, &channels[i]);
+                                       callback, NULL, &channels[i]);
                if (err < 0) {
                        int j;
                        for (j = 0; j < i; j++)
@@ -2297,13 +2297,13 @@ static int __init omap_init_dma(void)
        int ch, r;
 
        if (cpu_class_is_omap1()) {
-               omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP1_DMA_BASE);
+               omap_dma_base = IO_ADDRESS(OMAP1_DMA_BASE);
                dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
        } else if (cpu_is_omap24xx()) {
-               omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP24XX_DMA4_BASE);
+               omap_dma_base = IO_ADDRESS(OMAP24XX_DMA4_BASE);
                dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
        } else if (cpu_is_omap34xx()) {
-               omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP34XX_DMA4_BASE);
+               omap_dma_base = IO_ADDRESS(OMAP34XX_DMA4_BASE);
                dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
        } else {
                pr_err("DMA init failed for unsupported omap\n");
index 606fcffdcefcc98cd69f02c0f4f6225e72df8929..963c31cd15416b69aacd5ae253e393f641de0e8a 100644 (file)
@@ -693,7 +693,7 @@ int __init omap_dm_timer_init(void)
 
        for (i = 0; i < dm_timer_count; i++) {
                timer = &dm_timers[i];
-               timer->io_base = (void __iomem *)io_p2v(timer->phys_base);
+               timer->io_base = IO_ADDRESS(timer->phys_base);
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
                if (cpu_class_is_omap2()) {
                        char clk_name[16];
index 5935ae4e550b4f5514a211d897827f933e592295..8679fbca6bbec4ec3d5e5561b92c633cf1e6f298 100644 (file)
@@ -28,7 +28,7 @@
 /*
  * OMAP1510 GPIO registers
  */
-#define OMAP1510_GPIO_BASE             (void __iomem *)0xfffce000
+#define OMAP1510_GPIO_BASE             IO_ADDRESS(0xfffce000)
 #define OMAP1510_GPIO_DATA_INPUT       0x00
 #define OMAP1510_GPIO_DATA_OUTPUT      0x04
 #define OMAP1510_GPIO_DIR_CONTROL      0x08
 /*
  * OMAP1610 specific GPIO registers
  */
-#define OMAP1610_GPIO1_BASE            (void __iomem *)0xfffbe400
-#define OMAP1610_GPIO2_BASE            (void __iomem *)0xfffbec00
-#define OMAP1610_GPIO3_BASE            (void __iomem *)0xfffbb400
-#define OMAP1610_GPIO4_BASE            (void __iomem *)0xfffbbc00
+#define OMAP1610_GPIO1_BASE            IO_ADDRESS(0xfffbe400)
+#define OMAP1610_GPIO2_BASE            IO_ADDRESS(0xfffbec00)
+#define OMAP1610_GPIO3_BASE            IO_ADDRESS(0xfffbb400)
+#define OMAP1610_GPIO4_BASE            IO_ADDRESS(0xfffbbc00)
 #define OMAP1610_GPIO_REVISION         0x0000
 #define OMAP1610_GPIO_SYSCONFIG                0x0010
 #define OMAP1610_GPIO_SYSSTATUS                0x0014
 /*
  * OMAP730 specific GPIO registers
  */
-#define OMAP730_GPIO1_BASE             (void __iomem *)0xfffbc000
-#define OMAP730_GPIO2_BASE             (void __iomem *)0xfffbc800
-#define OMAP730_GPIO3_BASE             (void __iomem *)0xfffbd000
-#define OMAP730_GPIO4_BASE             (void __iomem *)0xfffbd800
-#define OMAP730_GPIO5_BASE             (void __iomem *)0xfffbe000
-#define OMAP730_GPIO6_BASE             (void __iomem *)0xfffbe800
+#define OMAP730_GPIO1_BASE             IO_ADDRESS(0xfffbc000)
+#define OMAP730_GPIO2_BASE             IO_ADDRESS(0xfffbc800)
+#define OMAP730_GPIO3_BASE             IO_ADDRESS(0xfffbd000)
+#define OMAP730_GPIO4_BASE             IO_ADDRESS(0xfffbd800)
+#define OMAP730_GPIO5_BASE             IO_ADDRESS(0xfffbe000)
+#define OMAP730_GPIO6_BASE             IO_ADDRESS(0xfffbe800)
 #define OMAP730_GPIO_DATA_INPUT                0x00
 #define OMAP730_GPIO_DATA_OUTPUT       0x04
 #define OMAP730_GPIO_DIR_CONTROL       0x08
 /*
  * omap24xx specific GPIO registers
  */
-#define OMAP242X_GPIO1_BASE            (void __iomem *)0x48018000
-#define OMAP242X_GPIO2_BASE            (void __iomem *)0x4801a000
-#define OMAP242X_GPIO3_BASE            (void __iomem *)0x4801c000
-#define OMAP242X_GPIO4_BASE            (void __iomem *)0x4801e000
+#define OMAP242X_GPIO1_BASE            IO_ADDRESS(0x48018000)
+#define OMAP242X_GPIO2_BASE            IO_ADDRESS(0x4801a000)
+#define OMAP242X_GPIO3_BASE            IO_ADDRESS(0x4801c000)
+#define OMAP242X_GPIO4_BASE            IO_ADDRESS(0x4801e000)
 
-#define OMAP243X_GPIO1_BASE            (void __iomem *)0x4900C000
-#define OMAP243X_GPIO2_BASE            (void __iomem *)0x4900E000
-#define OMAP243X_GPIO3_BASE            (void __iomem *)0x49010000
-#define OMAP243X_GPIO4_BASE            (void __iomem *)0x49012000
-#define OMAP243X_GPIO5_BASE            (void __iomem *)0x480B6000
+#define OMAP243X_GPIO1_BASE            IO_ADDRESS(0x4900C000)
+#define OMAP243X_GPIO2_BASE            IO_ADDRESS(0x4900E000)
+#define OMAP243X_GPIO3_BASE            IO_ADDRESS(0x49010000)
+#define OMAP243X_GPIO4_BASE            IO_ADDRESS(0x49012000)
+#define OMAP243X_GPIO5_BASE            IO_ADDRESS(0x480B6000)
 
 #define OMAP24XX_GPIO_REVISION         0x0000
 #define OMAP24XX_GPIO_SYSCONFIG                0x0010
  * omap34xx specific GPIO registers
  */
 
-#define OMAP34XX_GPIO1_BASE            (void __iomem *)0x48310000
-#define OMAP34XX_GPIO2_BASE            (void __iomem *)0x49050000
-#define OMAP34XX_GPIO3_BASE            (void __iomem *)0x49052000
-#define OMAP34XX_GPIO4_BASE            (void __iomem *)0x49054000
-#define OMAP34XX_GPIO5_BASE            (void __iomem *)0x49056000
-#define OMAP34XX_GPIO6_BASE            (void __iomem *)0x49058000
+#define OMAP34XX_GPIO1_BASE            IO_ADDRESS(0x48310000)
+#define OMAP34XX_GPIO2_BASE            IO_ADDRESS(0x49050000)
+#define OMAP34XX_GPIO3_BASE            IO_ADDRESS(0x49052000)
+#define OMAP34XX_GPIO4_BASE            IO_ADDRESS(0x49054000)
+#define OMAP34XX_GPIO5_BASE            IO_ADDRESS(0x49056000)
+#define OMAP34XX_GPIO6_BASE            IO_ADDRESS(0x49058000)
 
+#define OMAP_MPUIO_VBASE               IO_ADDRESS(OMAP_MPUIO_BASE)
 
 struct gpio_bank {
        void __iomem *base;
@@ -160,7 +161,7 @@ struct gpio_bank {
 
 #ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
-       { OMAP_MPUIO_BASE,     INT_MPUIO,           IH_MPUIO_BASE,     METHOD_MPUIO},
+       { OMAP_MPUIO_VBASE,    INT_MPUIO,           IH_MPUIO_BASE,     METHOD_MPUIO},
        { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1,      IH_GPIO_BASE,      METHOD_GPIO_1610 },
        { OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
        { OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
@@ -170,14 +171,14 @@ static struct gpio_bank gpio_bank_1610[5] = {
 
 #ifdef CONFIG_ARCH_OMAP15XX
 static struct gpio_bank gpio_bank_1510[2] = {
-       { OMAP_MPUIO_BASE,    INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
+       { OMAP_MPUIO_VBASE,   INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
        { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
 };
 #endif
 
 #ifdef CONFIG_ARCH_OMAP730
 static struct gpio_bank gpio_bank_730[7] = {
-       { OMAP_MPUIO_BASE,     INT_730_MPUIO,       IH_MPUIO_BASE,      METHOD_MPUIO },
+       { OMAP_MPUIO_VBASE,    INT_730_MPUIO,       IH_MPUIO_BASE,      METHOD_MPUIO },
        { OMAP730_GPIO1_BASE,  INT_730_GPIO_BANK1,  IH_GPIO_BASE,       METHOD_GPIO_730 },
        { OMAP730_GPIO2_BASE,  INT_730_GPIO_BANK2,  IH_GPIO_BASE + 32,  METHOD_GPIO_730 },
        { OMAP730_GPIO3_BASE,  INT_730_GPIO_BANK3,  IH_GPIO_BASE + 64,  METHOD_GPIO_730 },
@@ -1389,7 +1390,7 @@ static int __init _omap_gpio_init(void)
 
                gpio_bank_count = 5;
                gpio_bank = gpio_bank_1610;
-               rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
+               rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
                printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
                       (rev >> 4) & 0x0f, rev & 0x0f);
        }
@@ -1408,7 +1409,7 @@ static int __init _omap_gpio_init(void)
 
                gpio_bank_count = 4;
                gpio_bank = gpio_bank_242x;
-               rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+               rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
                printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n",
                        (rev >> 4) & 0x0f, rev & 0x0f);
        }
@@ -1417,7 +1418,7 @@ static int __init _omap_gpio_init(void)
 
                gpio_bank_count = 5;
                gpio_bank = gpio_bank_243x;
-               rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+               rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
                printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n",
                        (rev >> 4) & 0x0f, rev & 0x0f);
        }
@@ -1428,7 +1429,7 @@ static int __init _omap_gpio_init(void)
 
                gpio_bank_count = OMAP34XX_NR_GPIOS;
                gpio_bank = gpio_bank_34xx;
-               rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+               rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
                printk(KERN_INFO "OMAP34xx GPIO hardware version %d.%d\n",
                        (rev >> 4) & 0x0f, rev & 0x0f);
        }
@@ -1437,10 +1438,9 @@ static int __init _omap_gpio_init(void)
                int j, gpio_count = 16;
 
                bank = &gpio_bank[i];
-               bank->base = IO_ADDRESS(bank->base);
                spin_lock_init(&bank->lock);
                if (bank_is_mpuio(bank))
-                       omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
+                       __raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT);
                if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
                        __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
                        __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
index cf1dc02239495a8a1f2762d4eba8290c01f4d856..10d449ea7ed0d728106117d9c9ee64cd3580c875 100644 (file)
 #define __ASM_ARCH_OMAP_2430SDP_H
 
 /* Placeholder for 2430SDP specific defines */
-#define OMAP24XX_ETHR_START             0x08000300
+#define OMAP24XX_ETHR_START            0x08000300
 #define OMAP24XX_ETHR_GPIO_IRQ         149
 #define SDP2430_CS0_BASE               0x04000000
 
-#define TWL4030_IRQNUM                 INT_24XX_SYS_NIRQ
+/* Function prototypes */
+extern void sdp2430_flash_init(void);
+extern void sdp2430_usb_init(void);
 
 #endif /* __ASM_ARCH_OMAP_2430SDP_H */
index d6f2a8e963d5c86340bec27d604217699341de04..731c858cf3fe70e836a9fbead02bee5ed7bfb5fa 100644 (file)
 
 extern void apollon_mmc_init(void);
 
+static inline int apollon_plus(void)
+{
+       /* The apollon plus has IDCODE revision 5 */
+       return system_rev & 0xc0;
+}
+
 /* Placeholder for APOLLON specific defines */
 #define APOLLON_ETHR_GPIO_IRQ          74
 
index 1470cd3e519b80d746388cb0414b0fa59f596d43..7c3fa0f0a65e1512b2efe9e55debfe199d87a789 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/plat-omap/include/mach/board-h4.h
  *
- * Hardware definitions for TI OMAP1610 H4 board.
+ * Hardware definitions for TI OMAP2420 H4 board.
  *
  * Initial creation by Dirk Behme <dirk.behme@de.bosch.com>
  *
@@ -29,6 +29,9 @@
 #ifndef __ASM_ARCH_OMAP_H4_H
 #define __ASM_ARCH_OMAP_H4_H
 
+/* MMC Prototypes */
+extern void h4_mmc_init(void);
+
 /* Placeholder for H4 specific defines */
 #define OMAP24XX_ETHR_GPIO_IRQ         92
 #endif /*  __ASM_ARCH_OMAP_H4_H */
diff --git a/arch/arm/plat-omap/include/mach/board-ldp.h b/arch/arm/plat-omap/include/mach/board-ldp.h
new file mode 100644 (file)
index 0000000..66e2746
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/plat-omap/include/mach/board-ldp.h
+ *
+ * Hardware definitions for TI OMAP3 LDP.
+ *
+ * Copyright (C) 2008 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS 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.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP_LDP_H
+#define __ASM_ARCH_OMAP_LDP_H
+
+extern void twl4030_bci_battery_init(void);
+
+#define TWL4030_IRQNUM         INT_34XX_SYS_NIRQ
+
+#endif /* __ASM_ARCH_OMAP_LDP_H */
diff --git a/arch/arm/plat-omap/include/mach/board-omap3beagle.h b/arch/arm/plat-omap/include/mach/board-omap3beagle.h
new file mode 100644 (file)
index 0000000..3080d52
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/plat-omap/include/mach/board-omap3beagle.h
+ *
+ * Hardware definitions for TI OMAP3 BEAGLE.
+ *
+ * Initial creation by Syed Mohammed Khasim <khasim@ti.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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP3_BEAGLE_H
+#define __ASM_ARCH_OMAP3_BEAGLE_H
+
+#endif /* __ASM_ARCH_OMAP3_BEAGLE_H */
+
diff --git a/arch/arm/plat-omap/include/mach/board-overo.h b/arch/arm/plat-omap/include/mach/board-overo.h
new file mode 100644 (file)
index 0000000..7ecae66
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * board-overo.h (Gumstix Overo)
+ *
+ * Initial code: Steve Sakoman <steve@sakoman.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.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_OVERO_H
+#define __ASM_ARCH_OVERO_H
+
+#define OVERO_GPIO_BT_XGATE    15
+#define OVERO_GPIO_W2W_NRESET  16
+#define OVERO_GPIO_BT_NRESET   164
+#define OVERO_GPIO_USBH_CPEN   168
+#define OVERO_GPIO_USBH_NRESET 183
+
+#endif /* ____ASM_ARCH_OVERO_H */
+
index 54445642f35d4ff4fd54e137fdcf845acdfb9238..c23c12ccb3532c912285a70ef012dd6b030ff5b1 100644 (file)
@@ -45,6 +45,8 @@ struct omap_mmc_conf {
        unsigned cover:1;
        /* 4 wire signaling is optional, and is only used for SD/SDIO */
        unsigned wire4:1;
+       /* use the internal clock */
+       unsigned internal_clock:1;
        s16 power_pin;
        s16 switch_pin;
        s16 wp_pin;
index 92f7c7238fcd9b94d019287dc1ea7ddd07fca472..719298554ed7ebc9647c931db05106e2b6c0e290 100644 (file)
@@ -15,6 +15,7 @@
 
 struct module;
 struct clk;
+struct clockdomain;
 
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 
@@ -79,6 +80,8 @@ struct clk {
        u32                     clksel_mask;
        const struct clksel     *clksel;
        struct dpll_data        *dpll_data;
+       const char              *clkdm_name;
+       struct clockdomain      *clkdm;
 #else
        __u8                    rate_offset;
        __u8                    src_offset;
diff --git a/arch/arm/plat-omap/include/mach/clockdomain.h b/arch/arm/plat-omap/include/mach/clockdomain.h
new file mode 100644 (file)
index 0000000..1f51f01
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * linux/include/asm-arm/arch-omap/clockdomain.h
+ *
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+
+#include <mach/powerdomain.h>
+#include <mach/clock.h>
+#include <mach/cpu.h>
+
+/* Clockdomain capability flags */
+#define CLKDM_CAN_FORCE_SLEEP                  (1 << 0)
+#define CLKDM_CAN_FORCE_WAKEUP                 (1 << 1)
+#define CLKDM_CAN_ENABLE_AUTO                  (1 << 2)
+#define CLKDM_CAN_DISABLE_AUTO                 (1 << 3)
+
+#define CLKDM_CAN_HWSUP                (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
+#define CLKDM_CAN_SWSUP                (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
+#define CLKDM_CAN_HWSUP_SWSUP  (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
+
+/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
+#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO                0x0
+#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO         0x1
+
+/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
+#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO                0x0
+#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP         0x1
+#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP                0x2
+#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO         0x3
+
+/*
+ * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
+ * and sleepdeps added when a powerdomain should stay active in hwsup mode;
+ * and conversely, removed when the powerdomain should be allowed to go
+ * inactive in hwsup mode.
+ */
+struct clkdm_pwrdm_autodep {
+
+       /* Name of the powerdomain to add a wkdep/sleepdep on */
+       const char *pwrdm_name;
+
+       /* Powerdomain pointer (looked up at clkdm_init() time) */
+       struct powerdomain *pwrdm;
+
+       /* OMAP chip types that this clockdomain dep is valid on */
+       const struct omap_chip_id omap_chip;
+
+};
+
+struct clockdomain {
+
+       /* Clockdomain name */
+       const char *name;
+
+       /* Powerdomain enclosing this clockdomain */
+       const char *pwrdm_name;
+
+       /* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
+       const u16 clktrctrl_mask;
+
+       /* Clockdomain capability flags */
+       const u8 flags;
+
+       /* OMAP chip types that this clockdomain is valid on */
+       const struct omap_chip_id omap_chip;
+
+       /* Usecount tracking */
+       atomic_t usecount;
+
+       /* Powerdomain pointer assigned at clkdm_register() */
+       struct powerdomain *pwrdm;
+
+       struct list_head node;
+
+};
+
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
+int clkdm_register(struct clockdomain *clkdm);
+int clkdm_unregister(struct clockdomain *clkdm);
+struct clockdomain *clkdm_lookup(const char *name);
+
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm));
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
+
+void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
+void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
+
+int omap2_clkdm_wakeup(struct clockdomain *clkdm);
+int omap2_clkdm_sleep(struct clockdomain *clkdm);
+
+int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
+int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+
+#endif
index 06093112b665c6b2b77330647f11938cfe898825..ef70e2b0f05413d78e246b27e17ab3602d690cea 100644 (file)
@@ -34,6 +34,7 @@ struct sys_timer;
 extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 extern void omap_serial_init(void);
+extern void omap_serial_enable_clocks(int enable);
 #ifdef CONFIG_I2C_OMAP
 extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
                                 struct i2c_board_info const *info,
@@ -49,6 +50,7 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
 
 /* IO bases for various OMAP processors */
 struct omap_globals {
+       u32             class;          /* OMAP class to detect */
        void __iomem    *tap;           /* Control module ID code */
        void __iomem    *sdrc;          /* SDRAM Controller */
        void __iomem    *sms;           /* SDRAM Memory Scheduler */
@@ -62,6 +64,7 @@ void omap2_set_globals_243x(void);
 void omap2_set_globals_343x(void);
 
 /* These get called from omap2_set_globals_xxxx(), do not call these */
+void omap2_set_globals_tap(struct omap_globals *);
 void omap2_set_globals_memory(struct omap_globals *);
 void omap2_set_globals_control(struct omap_globals *);
 void omap2_set_globals_prcm(struct omap_globals *);
index e3fd62d9a995115bc2514807a8203f52dfe31684..dc9886760577b4be3510571863f38cf03ba0e04c 100644 (file)
@@ -1,13 +1,10 @@
-#ifndef __ASM_ARCH_CONTROL_H
-#define __ASM_ARCH_CONTROL_H
-
 /*
  * arch/arm/plat-omap/include/mach/control.h
  *
  * OMAP2/3 System Control Module definitions
  *
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
  * the Free Software Foundation.
  */
 
+#ifndef __ASM_ARCH_CONTROL_H
+#define __ASM_ARCH_CONTROL_H
+
 #include <mach/io.h>
 
+#ifndef __ASSEMBLY__
 #define OMAP242X_CTRL_REGADDR(reg)                                     \
-       (void __iomem *)IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+       IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
 #define OMAP243X_CTRL_REGADDR(reg)                                     \
-       (void __iomem *)IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+       IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
 #define OMAP343X_CTRL_REGADDR(reg)                                     \
-       (void __iomem *)IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+       IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#else
+#define OMAP242X_CTRL_REGADDR(reg)     IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg)     IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg)     IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#endif /* __ASSEMBLY__ */
 
 /*
  * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for
 #define OMAP343X_CONTROL_TEST_KEY_13   (OMAP2_CONTROL_GENERAL + 0x00fc)
 #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
 #define OMAP343X_CONTROL_IVA2_BOOTMOD  (OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP343X_CONTROL_TEMP_SENSOR   (OMAP2_CONTROL_GENERAL + 0x02b4)
 
 /*
  * REVISIT: This list of registers is not comprehensive - there are more
index 05aee0eda34fb9de569e630bc966e59c4f1a8928..e0464187209dcc9d4227267e251944b1e7cd7337 100644 (file)
@@ -346,9 +346,14 @@ IS_OMAP_TYPE(3430, 0x3430)
                get_sil_revision(system_rev)
 
 /* Various silicon macros defined here */
+#define OMAP242X_CLASS         0x24200000
 #define OMAP2420_REV_ES1_0     0x24200000
 #define OMAP2420_REV_ES2_0     0x24201000
+
+#define OMAP243X_CLASS         0x24300000
 #define OMAP2430_REV_ES1_0     0x24300000
+
+#define OMAP343X_CLASS         0x34300000
 #define OMAP3430_REV_ES1_0     0x34300000
 #define OMAP3430_REV_ES2_0     0x34301000
 #define OMAP3430_REV_ES2_1     0x34302000
index 1b0039bdeb4ee28c0501e94d9c15afe9c060858e..1b11f5c6a2d9769d4acdc543a5fba4bd1a03636d 100644 (file)
 #ifdef CONFIG_OMAP_LL_DEBUG_UART3
                add     \rx, \rx, #0x00004000   @ UART 3
 #endif
+
+#elif  CONFIG_ARCH_OMAP3
+               moveq   \rx, #0x48000000        @ physical base address
+               movne   \rx, #0xd8000000        @ virtual base
+               orr     \rx, \rx, #0x0006a000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART2
+               add     \rx, \rx, #0x00002000   @ UART 2
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+               add     \rx, \rx, #0x00fb0000   @ UART 3
+               add     \rx, \rx, #0x00006000
+#endif
 #endif
                .endm
 
index d4e9043bf2013c23b08f34c9eefcba9322059c45..030118ee204a655065e733508f1feee26c7aa3f2 100644 (file)
 1510:
                .endm
 
-#elif defined(CONFIG_ARCH_OMAP24XX)
+#endif
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 
+#if defined(CONFIG_ARCH_OMAP24XX)
 #include <mach/omap24xx.h>
+#endif
+#if defined(CONFIG_ARCH_OMAP34XX)
+#include <mach/omap34xx.h>
+#endif
+
+#define INTCPS_SIR_IRQ_OFFSET  0x0040          /* Active interrupt number */
 
                .macro  disable_fiq
                .endm
@@ -79,7 +87,7 @@
                ldr     \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
                cmp     \irqnr, #0x0
 2222:
-               ldrne   \irqnr, [\base, #IRQ_SIR_IRQ]
+               ldrne   \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
 
                .endm
 
index c92e4b42b2899cc0e6fdad376813815734cd5341..f1864a652f7a9adde718fc646062db39a0941ceb 100644 (file)
@@ -34,9 +34,9 @@ extern void omap1510_fpga_init_irq(void);
  * ---------------------------------------------------------------------------
  */
 /* maps in the FPGA registers and the ETHR registers */
-#define H2P2_DBG_FPGA_BASE             0xE8000000      /* VA */
-#define H2P2_DBG_FPGA_SIZE             SZ_4K           /* SIZE */
-#define H2P2_DBG_FPGA_START            0x04000000      /* PA */
+#define H2P2_DBG_FPGA_BASE             IOMEM(0xE8000000)       /* VA */
+#define H2P2_DBG_FPGA_SIZE             SZ_4K                   /* SIZE */
+#define H2P2_DBG_FPGA_START            0x04000000              /* PA */
 
 #define H2P2_DBG_FPGA_ETHR_START       (H2P2_DBG_FPGA_START + 0x300)
 #define H2P2_DBG_FPGA_FPGA_REV         (H2P2_DBG_FPGA_BASE + 0x10)     /* FPGA Revision */
@@ -85,9 +85,9 @@ struct h2p2_dbg_fpga {
  *  OMAP-1510 FPGA
  * ---------------------------------------------------------------------------
  */
-#define OMAP1510_FPGA_BASE                     0xE8000000      /* Virtual */
-#define OMAP1510_FPGA_SIZE                     SZ_4K
-#define OMAP1510_FPGA_START                    0x08000000      /* Physical */
+#define OMAP1510_FPGA_BASE             IOMEM(0xE8000000)       /* VA */
+#define OMAP1510_FPGA_SIZE             SZ_4K
+#define OMAP1510_FPGA_START            0x08000000              /* PA */
 
 /* Revision */
 #define OMAP1510_FPGA_REV_LOW                  (OMAP1510_FPGA_BASE + 0x0)
index 8c71e288860fcec75a16f98ff0d0bbcc3b8fde34..98e9008b7e9d172ad06eb50a000cca0ef5443bb0 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/io.h>
 #include <mach/irqs.h>
 
-#define OMAP_MPUIO_BASE                        (void __iomem *)0xfffb5000
+#define OMAP_MPUIO_BASE                        0xfffb5000
 
 #ifdef CONFIG_ARCH_OMAP730
 #define OMAP_MPUIO_INPUT_LATCH         0x00
@@ -76,6 +76,8 @@ extern void omap_free_gpio(int gpio);
 extern void omap_set_gpio_direction(int gpio, int is_input);
 extern void omap_set_gpio_dataout(int gpio, int enable);
 extern int omap_get_gpio_datain(int gpio);
+extern void omap2_gpio_prepare_for_retention(void);
+extern void omap2_gpio_resume_after_retention(void);
 extern void omap_set_gpio_debounce(int gpio, int enable);
 extern void omap_set_gpio_debounce_time(int gpio, int enable);
 
index 6a8e07ffc2d03431b5da8b43b6a67122a212c071..45b678439bb70704b141dc823d0af33ec7237658 100644 (file)
@@ -11,6 +11,9 @@
 #ifndef __OMAP2_GPMC_H
 #define __OMAP2_GPMC_H
 
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM            8
+
 #define GPMC_CS_CONFIG1                0x00
 #define GPMC_CS_CONFIG2                0x04
 #define GPMC_CS_CONFIG3                0x08
@@ -22,6 +25,9 @@
 #define GPMC_CS_NAND_ADDRESS   0x20
 #define GPMC_CS_NAND_DATA      0x24
 
+#define GPMC_CONFIG            0x50
+#define GPMC_STATUS            0x54
+
 #define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
 #define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
 #define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
@@ -78,9 +84,14 @@ struct gpmc_timings {
        u16 access;             /* Start-cycle to first data valid delay */
        u16 rd_cycle;           /* Total read cycle time */
        u16 wr_cycle;           /* Total write cycle time */
+
+       /* The following are only on OMAP3430 */
+       u16 wr_access;          /* WRACCESSTIME */
+       u16 wr_data_mux_bus;    /* WRDATAONADMUXBUS */
 };
 
 extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
 extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
 extern unsigned long gpmc_get_fclk_period(void);
 
@@ -92,5 +103,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern int gpmc_cs_set_reserved(int cs, int reserved);
 extern int gpmc_cs_reserved(int cs);
+extern void gpmc_init(void);
 
 #endif
index 07f5d7f21528874c11091d7ec982c87465a051d6..6589ddbb63b2a4c17ea5b91965c7895cdc4c1b33 100644 (file)
@@ -89,7 +89,7 @@
 #define DPLL_CTL               (0xfffecf00)
 
 /* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
-#define DSP_CONFIG_REG_BASE     (0xe1008000)
+#define DSP_CONFIG_REG_BASE     IOMEM(0xe1008000)
 #define DSP_CKCTL              (DSP_CONFIG_REG_BASE + 0x0)
 #define DSP_IDLECT1            (DSP_CONFIG_REG_BASE + 0x4)
 #define DSP_IDLECT2            (DSP_CONFIG_REG_BASE + 0x8)
 
 #include "omap730.h"
 #include "omap1510.h"
-#include "omap24xx.h"
 #include "omap16xx.h"
+#include "omap24xx.h"
 #include "omap34xx.h"
 
 #ifndef __ASSEMBLER__
 #include "board-2430sdp.h"
 #endif
 
+#ifdef CONFIG_MACH_OMAP3_BEAGLE
+#include "board-omap3beagle.h"
+#endif
+
+#ifdef CONFIG_MACH_OMAP_LDP
+#include "board-ldp.h"
+#endif
+
 #ifdef CONFIG_MACH_OMAP_APOLLON
 #include "board-apollon.h"
 #endif
index 2a30b7d88cdeae71cff778ae13c90bbb65d950f7..adc83b7b82052f296dae128af5597084ed1c1e45 100644 (file)
 
 #if defined(CONFIG_ARCH_OMAP1)
 
-#define IO_PHYS                0xFFFB0000
-#define IO_OFFSET      0x01000000      /* Virtual IO = 0xfefb0000 */
-#define IO_SIZE                0x40000
-#define IO_VIRT                (IO_PHYS - IO_OFFSET)
-#define IO_ADDRESS(pa) ((pa) - IO_OFFSET)
-#define OMAP1_IO_ADDRESS(pa)   ((pa) - IO_OFFSET)
-#define io_p2v(pa)     ((pa) - IO_OFFSET)
-#define io_v2p(va)     ((va) + IO_OFFSET)
+#define IO_PHYS                        0xFFFB0000
+#define IO_OFFSET              0x01000000      /* Virtual IO = 0xfefb0000 */
+#define IO_SIZE                        0x40000
+#define IO_VIRT                        (IO_PHYS - IO_OFFSET)
+#define __IO_ADDRESS(pa)       ((pa) - IO_OFFSET)
+#define __OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET)
+#define io_v2p(va)             ((va) + IO_OFFSET)
 
 #elif defined(CONFIG_ARCH_OMAP2)
 
@@ -74,7 +73,6 @@
 #define L4_24XX_VIRT   0xd8000000
 #define L4_24XX_SIZE   SZ_1M           /* 1MB of 128MB used, want 1MB sect */
 
-#ifdef CONFIG_ARCH_OMAP2430
 #define L4_WK_243X_PHYS                L4_WK_243X_BASE         /* 0x49000000 */
 #define L4_WK_243X_VIRT                0xd9000000
 #define L4_WK_243X_SIZE                SZ_1M
 #define OMAP243X_SMS_VIRT      0xFC000000
 #define OMAP243X_SMS_SIZE      SZ_1M
 
-#endif
-
-#define IO_OFFSET      0x90000000
-#define IO_ADDRESS(pa) ((pa) + IO_OFFSET)      /* Works for L3 and L4 */
-#define OMAP2_IO_ADDRESS(pa)   ((pa) + IO_OFFSET)      /* Works for L3 and L4 */
-#define io_p2v(pa)     ((pa) + IO_OFFSET)      /* Works for L3 and L4 */
-#define io_v2p(va)     ((va) - IO_OFFSET)      /* Works for L3 and L4 */
+#define IO_OFFSET              0x90000000
+#define __IO_ADDRESS(pa)       ((pa) + IO_OFFSET)      /* Works for L3 and L4 */
+#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)      /* Works for L3 and L4 */
+#define io_v2p(va)             ((va) - IO_OFFSET)      /* Works for L3 and L4 */
 
 /* DSP */
 #define DSP_MEM_24XX_PHYS      OMAP2420_DSP_MEM_BASE   /* 0x58000000 */
 
 
 #define IO_OFFSET              0x90000000
-#define IO_ADDRESS(pa)         ((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define OMAP2_IO_ADDRESS(pa)   ((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define io_p2v(pa)             ((pa) + IO_OFFSET)/* Works for L3 and L4 */
+#define __IO_ADDRESS(pa)       ((pa) + IO_OFFSET)/* Works for L3 and L4 */
+#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
 #define io_v2p(va)             ((va) - IO_OFFSET)/* Works for L3 and L4 */
 
 /* DSP */
 
 #endif
 
-#ifndef __ASSEMBLER__
+#define IO_ADDRESS(pa)         IOMEM(__IO_ADDRESS(pa))
+#define OMAP1_IO_ADDRESS(pa)   IOMEM(__OMAP1_IO_ADDRESS(pa))
+#define OMAP2_IO_ADDRESS(pa)   IOMEM(__OMAP2_IO_ADDRESS(pa))
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)               x
+#else
+#define IOMEM(x)               ((void __force __iomem *)(x))
 
 /*
  * Functions to access the OMAP IO region
  *      - DO NOT use hardcoded virtual addresses to allow changing the
  *        IO address space again if needed
  */
-#define omap_readb(a)          (*(volatile unsigned char  *)IO_ADDRESS(a))
-#define omap_readw(a)          (*(volatile unsigned short *)IO_ADDRESS(a))
-#define omap_readl(a)          (*(volatile unsigned int   *)IO_ADDRESS(a))
+#define omap_readb(a)          __raw_readb(IO_ADDRESS(a))
+#define omap_readw(a)          __raw_readw(IO_ADDRESS(a))
+#define omap_readl(a)          __raw_readl(IO_ADDRESS(a))
 
-#define omap_writeb(v,a)       (*(volatile unsigned char  *)IO_ADDRESS(a) = (v))
-#define omap_writew(v,a)       (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
-#define omap_writel(v,a)       (*(volatile unsigned int   *)IO_ADDRESS(a) = (v))
+#define omap_writeb(v,a)       __raw_writeb(v, IO_ADDRESS(a))
+#define omap_writew(v,a)       __raw_writew(v, IO_ADDRESS(a))
+#define omap_writel(v,a)       __raw_writel(v, IO_ADDRESS(a))
 
 extern void omap1_map_common_io(void);
 extern void omap1_init_common_hw(void);
@@ -192,6 +193,12 @@ extern void omap1_init_common_hw(void);
 extern void omap2_map_common_io(void);
 extern void omap2_init_common_hw(void);
 
+#define __arch_ioremap(p,s,t)  omap_ioremap(p,s,t)
+#define __arch_iounmap(v)      omap_iounmap(v)
+
+void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
+void omap_iounmap(volatile void __iomem *addr);
+
 #endif
 
 #endif
index 62aa7dfb9464c9ef375acc6d2ac1283413f4486e..a2929ac8c68733a6e4b606d5737a01a9fafb3fb8 100644 (file)
 #define INT_UART2              (15 + IH2_BASE)
 #define INT_BT_MCSI1TX         (16 + IH2_BASE)
 #define INT_BT_MCSI1RX         (17 + IH2_BASE)
+#define INT_SOSSI_MATCH                (19 + IH2_BASE)
 #define INT_USB_W2FC           (20 + IH2_BASE)
 #define INT_1WIRE              (21 + IH2_BASE)
 #define INT_OS_TIMER           (22 + IH2_BASE)
 #define INT_1610_DMA_CH14      (61 + IH2_BASE)
 #define INT_1610_DMA_CH15      (62 + IH2_BASE)
 #define INT_1610_NAND          (63 + IH2_BASE)
+#define INT_1610_SHA1MD5       (91 + IH2_BASE)
 
 /*
  * OMAP-730 specific IRQ numbers for interrupt handler 2
 #define INT_24XX_GPTIMER10     46
 #define INT_24XX_GPTIMER11     47
 #define INT_24XX_GPTIMER12     48
+#define INT_24XX_SHA1MD5       51
+#define INT_24XX_MCBSP4_IRQ_TX 54
+#define INT_24XX_MCBSP4_IRQ_RX 55
 #define INT_24XX_I2C1_IRQ      56
 #define INT_24XX_I2C2_IRQ      57
+#define INT_24XX_HDQ_IRQ       58
 #define INT_24XX_MCBSP1_IRQ_TX 59
 #define INT_24XX_MCBSP1_IRQ_RX 60
 #define INT_24XX_MCBSP2_IRQ_TX 62
 #define INT_24XX_MCBSP2_IRQ_RX 63
+#define INT_24XX_SPI1_IRQ      65
+#define INT_24XX_SPI2_IRQ      66
 #define INT_24XX_UART1_IRQ     72
 #define INT_24XX_UART2_IRQ     73
 #define INT_24XX_UART3_IRQ     74
 #define INT_24XX_USB_IRQ_HGEN  78
 #define INT_24XX_USB_IRQ_HSOF  79
 #define INT_24XX_USB_IRQ_OTG   80
+#define INT_24XX_MCBSP5_IRQ_TX 81
+#define INT_24XX_MCBSP5_IRQ_RX 82
 #define INT_24XX_MMC_IRQ       83
+#define INT_24XX_MMC2_IRQ      86
+#define INT_24XX_MCBSP3_IRQ_TX 89
+#define INT_24XX_MCBSP3_IRQ_RX 90
+#define INT_24XX_SPI3_IRQ      91
+
+#define INT_243X_MCBSP2_IRQ    16
+#define INT_243X_MCBSP3_IRQ    17
+#define INT_243X_MCBSP4_IRQ    18
+#define INT_243X_MCBSP5_IRQ    19
+#define INT_243X_MCBSP1_IRQ    64
+#define INT_243X_HS_USB_MC     92
+#define INT_243X_HS_USB_DMA    93
+#define INT_243X_CARKIT_IRQ    94
+
+#define INT_34XX_BENCH_MPU_EMUL        3
+#define INT_34XX_ST_MCBSP2_IRQ 4
+#define INT_34XX_ST_MCBSP3_IRQ 5
+#define INT_34XX_SSM_ABORT_IRQ 6
+#define INT_34XX_SYS_NIRQ      7
+#define INT_34XX_D2D_FW_IRQ    8
+#define INT_34XX_PRCM_MPU_IRQ  11
+#define INT_34XX_MCBSP1_IRQ    16
+#define INT_34XX_MCBSP2_IRQ    17
+#define INT_34XX_MCBSP3_IRQ    22
+#define INT_34XX_MCBSP4_IRQ    23
+#define INT_34XX_CAM_IRQ       24
+#define INT_34XX_MCBSP5_IRQ    27
+#define INT_34XX_GPIO_BANK1    29
+#define INT_34XX_GPIO_BANK2    30
+#define INT_34XX_GPIO_BANK3    31
+#define INT_34XX_GPIO_BANK4    32
+#define INT_34XX_GPIO_BANK5    33
+#define INT_34XX_GPIO_BANK6    34
+#define INT_34XX_USIM_IRQ      35
+#define INT_34XX_WDT3_IRQ      36
+#define INT_34XX_SPI4_IRQ      48
+#define INT_34XX_SHA1MD52_IRQ  49
+#define INT_34XX_FPKA_READY_IRQ        50
+#define INT_34XX_SHA1MD51_IRQ  51
+#define INT_34XX_RNG_IRQ       52
+#define INT_34XX_I2C3_IRQ      61
+#define INT_34XX_FPKA_ERROR_IRQ        64
+#define INT_34XX_PBIAS_IRQ     75
+#define INT_34XX_OHCI_IRQ      76
+#define INT_34XX_EHCI_IRQ      77
+#define INT_34XX_TLL_IRQ       78
+#define INT_34XX_PARTHASH_IRQ  79
+#define INT_34XX_MMC3_IRQ      94
+#define INT_34XX_GPT12_IRQ     95
 
 #define        INT_34XX_BENCH_MPU_EMUL 3
 
index 8fdb95e26fcd86775fe4fd494139e381b17f76e5..6a0d1a0a24a7d86f2f767130de8ed9ea95073e3c 100644 (file)
 
 #define OMAP24XX_MCBSP1_BASE   0x48074000
 #define OMAP24XX_MCBSP2_BASE   0x48076000
+#define OMAP2430_MCBSP3_BASE   0x4808c000
+#define OMAP2430_MCBSP4_BASE   0x4808e000
+#define OMAP2430_MCBSP5_BASE   0x48096000
 
 #define OMAP34XX_MCBSP1_BASE   0x48074000
 #define OMAP34XX_MCBSP2_BASE   0x49022000
+#define OMAP34XX_MCBSP3_BASE   0x49024000
+#define OMAP34XX_MCBSP4_BASE   0x49026000
+#define OMAP34XX_MCBSP5_BASE   0x48096000
 
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
 
@@ -81,9 +87,6 @@
 #define OMAP_MCBSP_REG_XCERG   0x3A
 #define OMAP_MCBSP_REG_XCERH   0x3C
 
-#define OMAP_MAX_MCBSP_COUNT   3
-#define MAX_MCBSP_CLOCKS       3
-
 #define AUDIO_MCBSP_DATAWRITE  (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
 #define AUDIO_MCBSP_DATAREAD   (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
 
 #define AUDIO_DMA_TX           OMAP_DMA_MCBSP1_TX
 #define AUDIO_DMA_RX           OMAP_DMA_MCBSP1_RX
 
-#elif defined(CONFIG_ARCH_OMAP24XX)
+#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 
 #define OMAP_MCBSP_REG_DRR2    0x00
 #define OMAP_MCBSP_REG_DRR1    0x04
 #define OMAP_MCBSP_REG_DXR2    0x08
 #define OMAP_MCBSP_REG_DXR1    0x0C
+#define OMAP_MCBSP_REG_DRR     0x00
+#define OMAP_MCBSP_REG_DXR     0x08
 #define OMAP_MCBSP_REG_SPCR2   0x10
 #define OMAP_MCBSP_REG_SPCR1   0x14
 #define OMAP_MCBSP_REG_RCR2    0x18
 #define OMAP_MCBSP_REG_RCERH   0x70
 #define OMAP_MCBSP_REG_XCERG   0x74
 #define OMAP_MCBSP_REG_XCERH   0x78
-
-#define OMAP_MAX_MCBSP_COUNT   2
-#define MAX_MCBSP_CLOCKS       2
+#define OMAP_MCBSP_REG_SYSCON  0x8C
+#define OMAP_MCBSP_REG_XCCR    0xAC
+#define OMAP_MCBSP_REG_RCCR    0xB0
 
 #define AUDIO_MCBSP_DATAWRITE  (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
 #define AUDIO_MCBSP_DATAREAD   (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
 
 #endif
 
-#define OMAP_MCBSP_READ(base, reg)             __raw_readw((base) + OMAP_MCBSP_REG_##reg)
-#define OMAP_MCBSP_WRITE(base, reg, val)       __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg)
-
-
 /************************** McBSP SPCR1 bit definitions ***********************/
 #define RRST                   0x0001
 #define RRDY                   0x0002
 #define DXENA                  0x0080
 #define CLKSTP(value)          ((value)<<11)   /* bits 11:12 */
 #define RJUST(value)           ((value)<<13)   /* bits 13:14 */
+#define ALB                    0x8000
 #define DLB                    0x8000
 
 /************************** McBSP SPCR2 bit definitions ***********************/
 #define XPABLK(value)          ((value)<<5)    /* Bits 5:6 */
 #define XPBBLK(value)          ((value)<<7)    /* Bits 7:8 */
 
+/*********************** McBSP XCCR bit definitions *************************/
+#define DILB                   0x0020
+#define XDMAEN                 0x0008
+#define XDISABLE               0x0001
+
+/********************** McBSP RCCR bit definitions *************************/
+#define RDMAEN                 0x0008
+#define RDISABLE               0x0001
+
+/********************** McBSP SYSCONFIG bit definitions ********************/
+#define SOFTRST                        0x0002
 
 /* we don't do multichannel for now */
 struct omap_mcbsp_reg_cfg {
@@ -260,6 +273,8 @@ typedef enum {
        OMAP_MCBSP1 = 0,
        OMAP_MCBSP2,
        OMAP_MCBSP3,
+       OMAP_MCBSP4,
+       OMAP_MCBSP5
 } omap_mcbsp_id;
 
 typedef int __bitwise omap_mcbsp_io_type_t;
@@ -311,12 +326,10 @@ struct omap_mcbsp_spi_cfg {
 struct omap_mcbsp_ops {
        void (*request)(unsigned int);
        void (*free)(unsigned int);
-       int (*check)(unsigned int);
 };
 
 struct omap_mcbsp_platform_data {
        unsigned long phys_base;
-       u32 virt_base;
        u8 dma_rx_sync, dma_tx_sync;
        u16 rx_irq, tx_irq;
        struct omap_mcbsp_ops *ops;
@@ -326,7 +339,7 @@ struct omap_mcbsp_platform_data {
 struct omap_mcbsp {
        struct device *dev;
        unsigned long phys_base;
-       u32 io_base;
+       void __iomem *io_base;
        u8 id;
        u8 free;
        omap_mcbsp_word_length rx_word_length;
@@ -354,6 +367,8 @@ struct omap_mcbsp {
        struct omap_mcbsp_platform_data *pdata;
        struct clk *clk;
 };
+extern struct omap_mcbsp **mcbsp_ptr;
+extern int omap_mcbsp_count;
 
 int omap_mcbsp_init(void);
 void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
@@ -378,5 +393,6 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg *
 /* Polled read/write functions */
 int omap_mcbsp_pollread(unsigned int id, u16 * buf);
 int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
+int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
 
 #endif
index a325caf80d04b9a18928a7b6478a64ab4f5338e3..d40cac60b95986043e4ff9bb4fce21bea5a6b1fa 100644 (file)
@@ -38,7 +38,7 @@
  */
 #if defined(CONFIG_ARCH_OMAP1)
 #define PHYS_OFFSET            UL(0x10000000)
-#elif defined(CONFIG_ARCH_OMAP2)
+#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 #define PHYS_OFFSET            UL(0x80000000)
 #endif
 
index 614b2c1327c747b77b5c693979babc566bd66d02..6bbf1789bed5debac64e2f9a7bc4ab0b19c0a834 100644 (file)
        .pu_pd_val      = pull_mode,                            \
 },
 
-
-#define PULL_DISABLED  0
-#define PULL_ENABLED   1
-
-#define PULL_DOWN      0
-#define PULL_UP                1
+/* 24xx/34xx mux bit defines */
+#define OMAP2_PULL_ENA         (1 << 3)
+#define OMAP2_PULL_UP          (1 << 4)
+#define OMAP2_ALTELECTRICALSEL (1 << 5)
+
+/* 34xx specific mux bit defines */
+#define OMAP3_INPUT_EN         (1 << 8)
+#define OMAP3_OFF_EN           (1 << 9)
+#define OMAP3_OFFOUT_EN                (1 << 10)
+#define OMAP3_OFFOUT_VAL       (1 << 11)
+#define OMAP3_OFF_PULL_EN      (1 << 12)
+#define OMAP3_OFF_PULL_UP      (1 << 13)
+#define OMAP3_WAKEUP_EN                (1 << 14)
+
+/* 34xx mux mode options for each pin. See TRM for options */
+#define        OMAP34XX_MUX_MODE0      0
+#define        OMAP34XX_MUX_MODE1      1
+#define        OMAP34XX_MUX_MODE2      2
+#define        OMAP34XX_MUX_MODE3      3
+#define        OMAP34XX_MUX_MODE4      4
+#define        OMAP34XX_MUX_MODE5      5
+#define        OMAP34XX_MUX_MODE6      6
+#define        OMAP34XX_MUX_MODE7      7
+
+/* 34xx active pin states */
+#define OMAP34XX_PIN_OUTPUT            0
+#define OMAP34XX_PIN_INPUT             OMAP3_INPUT_EN
+#define OMAP34XX_PIN_INPUT_PULLUP      (OMAP2_PULL_ENA | OMAP3_INPUT_EN \
+                                               | OMAP2_PULL_UP)
+#define OMAP34XX_PIN_INPUT_PULLDOWN    (OMAP2_PULL_ENA | OMAP3_INPUT_EN)
+
+/* 34xx off mode states */
+#define OMAP34XX_PIN_OFF_NONE           0
+#define OMAP34XX_PIN_OFF_OUTPUT_HIGH   (OMAP3_OFF_EN | OMAP3_OFFOUT_EN \
+                                               | OMAP3_OFFOUT_VAL)
+#define OMAP34XX_PIN_OFF_OUTPUT_LOW    (OMAP3_OFF_EN | OMAP3_OFFOUT_EN)
+#define OMAP34XX_PIN_OFF_INPUT_PULLUP  (OMAP3_OFF_EN | OMAP3_OFF_PULL_EN \
+                                               | OMAP3_OFF_PULL_UP)
+#define OMAP34XX_PIN_OFF_INPUT_PULLDOWN        (OMAP3_OFF_EN | OMAP3_OFF_PULL_EN)
+#define OMAP34XX_PIN_OFF_WAKEUPENABLE  OMAP3_WAKEUP_EN
+
+#define MUX_CFG_34XX(desc, reg_offset, mux_value) {            \
+       .name           = desc,                                 \
+       .debug          = 0,                                    \
+       .mux_reg        = reg_offset,                           \
+       .mux_val        = mux_value                             \
+},
 
 struct pin_config {
-       char *name;
-       unsigned char busy;
-       unsigned char debug;
+       char                    *name;
+       const unsigned int      mux_reg;
+       unsigned char           debug;
 
-       const char *mux_reg_name;
-       const unsigned int mux_reg;
+#if    defined(CONFIG_ARCH_OMAP34XX)
+       u16                     mux_val; /* Wake-up, off mode, pull, mux mode */
+#endif
+
+#if    defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
        const unsigned char mask_offset;
        const unsigned char mask;
 
@@ -150,6 +194,12 @@ struct pin_config {
        const char *pu_pd_name;
        const unsigned int pu_pd_reg;
        const unsigned char pu_pd_val;
+#endif
+
+#if    defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
+       const char *mux_reg_name;
+#endif
+
 };
 
 enum omap730_index {
@@ -593,6 +643,114 @@ enum omap24xx_index {
 
 };
 
+enum omap34xx_index {
+       /* 34xx I2C */
+       K21_34XX_I2C1_SCL,
+       J21_34XX_I2C1_SDA,
+       AF15_34XX_I2C2_SCL,
+       AE15_34XX_I2C2_SDA,
+       AF14_34XX_I2C3_SCL,
+       AG14_34XX_I2C3_SDA,
+       AD26_34XX_I2C4_SCL,
+       AE26_34XX_I2C4_SDA,
+
+       /* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
+       Y8_3430_USB1HS_PHY_CLK,
+       Y9_3430_USB1HS_PHY_STP,
+       AA14_3430_USB1HS_PHY_DIR,
+       AA11_3430_USB1HS_PHY_NXT,
+       W13_3430_USB1HS_PHY_DATA0,
+       W12_3430_USB1HS_PHY_DATA1,
+       W11_3430_USB1HS_PHY_DATA2,
+       Y11_3430_USB1HS_PHY_DATA3,
+       W9_3430_USB1HS_PHY_DATA4,
+       Y12_3430_USB1HS_PHY_DATA5,
+       W8_3430_USB1HS_PHY_DATA6,
+       Y13_3430_USB1HS_PHY_DATA7,
+
+       /* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
+       AA8_3430_USB2HS_PHY_CLK,
+       AA10_3430_USB2HS_PHY_STP,
+       AA9_3430_USB2HS_PHY_DIR,
+       AB11_3430_USB2HS_PHY_NXT,
+       AB10_3430_USB2HS_PHY_DATA0,
+       AB9_3430_USB2HS_PHY_DATA1,
+       W3_3430_USB2HS_PHY_DATA2,
+       T4_3430_USB2HS_PHY_DATA3,
+       T3_3430_USB2HS_PHY_DATA4,
+       R3_3430_USB2HS_PHY_DATA5,
+       R4_3430_USB2HS_PHY_DATA6,
+       T2_3430_USB2HS_PHY_DATA7,
+
+
+       /* TLL - HSUSB: 12-pin TLL Port 1*/
+       Y8_3430_USB1HS_TLL_CLK,
+       Y9_3430_USB1HS_TLL_STP,
+       AA14_3430_USB1HS_TLL_DIR,
+       AA11_3430_USB1HS_TLL_NXT,
+       W13_3430_USB1HS_TLL_DATA0,
+       W12_3430_USB1HS_TLL_DATA1,
+       W11_3430_USB1HS_TLL_DATA2,
+       Y11_3430_USB1HS_TLL_DATA3,
+       W9_3430_USB1HS_TLL_DATA4,
+       Y12_3430_USB1HS_TLL_DATA5,
+       W8_3430_USB1HS_TLL_DATA6,
+       Y13_3430_USB1HS_TLL_DATA7,
+
+       /* TLL - HSUSB: 12-pin TLL Port 2*/
+       AA8_3430_USB2HS_TLL_CLK,
+       AA10_3430_USB2HS_TLL_STP,
+       AA9_3430_USB2HS_TLL_DIR,
+       AB11_3430_USB2HS_TLL_NXT,
+       AB10_3430_USB2HS_TLL_DATA0,
+       AB9_3430_USB2HS_TLL_DATA1,
+       W3_3430_USB2HS_TLL_DATA2,
+       T4_3430_USB2HS_TLL_DATA3,
+       T3_3430_USB2HS_TLL_DATA4,
+       R3_3430_USB2HS_TLL_DATA5,
+       R4_3430_USB2HS_TLL_DATA6,
+       T2_3430_USB2HS_TLL_DATA7,
+
+       /* TLL - HSUSB: 12-pin TLL Port 3*/
+       AA6_3430_USB3HS_TLL_CLK,
+       AB3_3430_USB3HS_TLL_STP,
+       AA3_3430_USB3HS_TLL_DIR,
+       Y3_3430_USB3HS_TLL_NXT,
+       AA5_3430_USB3HS_TLL_DATA0,
+       Y4_3430_USB3HS_TLL_DATA1,
+       Y5_3430_USB3HS_TLL_DATA2,
+       W5_3430_USB3HS_TLL_DATA3,
+       AB12_3430_USB3HS_TLL_DATA4,
+       AB13_3430_USB3HS_TLL_DATA5,
+       AA13_3430_USB3HS_TLL_DATA6,
+       AA12_3430_USB3HS_TLL_DATA7,
+
+       /* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
+       AF10_3430_USB1FS_PHY_MM1_RXDP,
+       AG9_3430_USB1FS_PHY_MM1_RXDM,
+       W13_3430_USB1FS_PHY_MM1_RXRCV,
+       W12_3430_USB1FS_PHY_MM1_TXSE0,
+       W11_3430_USB1FS_PHY_MM1_TXDAT,
+       Y11_3430_USB1FS_PHY_MM1_TXEN_N,
+
+       /* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
+       AF7_3430_USB2FS_PHY_MM2_RXDP,
+       AH7_3430_USB2FS_PHY_MM2_RXDM,
+       AB10_3430_USB2FS_PHY_MM2_RXRCV,
+       AB9_3430_USB2FS_PHY_MM2_TXSE0,
+       W3_3430_USB2FS_PHY_MM2_TXDAT,
+       T4_3430_USB2FS_PHY_MM2_TXEN_N,
+
+       /* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
+       AH3_3430_USB3FS_PHY_MM3_RXDP,
+       AE3_3430_USB3FS_PHY_MM3_RXDM,
+       AD1_3430_USB3FS_PHY_MM3_RXRCV,
+       AE1_3430_USB3FS_PHY_MM3_TXSE0,
+       AD2_3430_USB3FS_PHY_MM3_TXDAT,
+       AC1_3430_USB3FS_PHY_MM3_TXEN_N,
+
+};
+
 struct omap_mux_cfg {
        struct pin_config       *pins;
        unsigned long           size;
index 505a38af8b22a36376c65e2374cf7b13d8f42361..d240046681381e071f98f1187d425b119e7b7594 100644 (file)
@@ -44,5 +44,7 @@
 #define OMAP1510_DSPREG_SIZE   SZ_128K
 #define OMAP1510_DSPREG_START  0xE1000000
 
+#define OMAP1510_DSP_MMU_BASE  (0xfffed200)
+
 #endif /*  __ASM_ARCH_OMAP15XX_H */
 
index c6c93afb2788f4b00911a67ec6d538570ec4a7ca..0e69b504c25fa1231a0fc1bd0f800432b50c57c2 100644 (file)
 #define OMAP16XX_DSPREG_SIZE   SZ_128K
 #define OMAP16XX_DSPREG_START  0xE1000000
 
+#define OMAP16XX_SEC_BASE      0xFFFE4000
+#define OMAP16XX_SEC_DES       (OMAP16XX_SEC_BASE + 0x0000)
+#define OMAP16XX_SEC_SHA1MD5   (OMAP16XX_SEC_BASE + 0x0800)
+#define OMAP16XX_SEC_RNG       (OMAP16XX_SEC_BASE + 0x1000)
+
 /*
  * ---------------------------------------------------------------------------
  * Interrupts
 #define WSPR_DISABLE_0         (0x0000aaaa)
 #define WSPR_DISABLE_1         (0x00005555)
 
-/* Mailbox */
+#define OMAP16XX_DSP_MMU_BASE  (0xfffed200)
 #define OMAP16XX_MAILBOX_BASE  (0xfffcf000)
 
 #endif /*  __ASM_ARCH_OMAP16XX_H */
index bb8319d66e9f5afa64a2798ccaca93ee98e76d57..24335d4932f5c725a13583197633bcd08fced549 100644 (file)
@@ -39,7 +39,6 @@
 /* interrupt controller */
 #define OMAP24XX_IC_BASE       (L4_24XX_BASE + 0xfe000)
 #define OMAP24XX_IVA_INTC_BASE 0x40000000
-#define IRQ_SIR_IRQ            0x0040
 
 #define OMAP2420_CTRL_BASE     L4_24XX_BASE
 #define OMAP2420_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
@@ -48,6 +47,7 @@
 #define OMAP2420_PRM_BASE      OMAP2420_CM_BASE
 #define OMAP2420_SDRC_BASE     (L3_24XX_BASE + 0x9000)
 #define OMAP2420_SMS_BASE      0x68008000
+#define OMAP2420_GPMC_BASE     0x6800a000
 
 #define OMAP2430_32KSYNCT_BASE (L4_WK_243X_BASE + 0x20000)
 #define OMAP2430_PRCM_BASE     (L4_WK_243X_BASE + 0x6000)
index cae037d130792a7c466a697d079b475c2f756e8b..ec67fb428607c55ba7d4e452db241cd048e7028c 100644 (file)
@@ -62,6 +62,7 @@
 #define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE        0x00010000
 #define OMAPFB_CAPS_WINDOW_SCALE       0x00020000
 #define OMAPFB_CAPS_WINDOW_OVERLAY     0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE      0x00080000
 #define OMAPFB_CAPS_SET_BACKLIGHT      0x01000000
 
 /* Values from DSP must map to lower 16-bits */
@@ -305,6 +306,7 @@ struct lcd_ctrl {
                                           int screen_width,
                                           int pos_x, int pos_y, int width,
                                           int height, int color_mode);
+       int             (*set_rotate)     (int angle);
        int             (*setup_mem)      (int plane, size_t size,
                                           int mem_type, unsigned long *paddr);
        int             (*mmap)           (struct fb_info *info,
@@ -374,6 +376,7 @@ extern struct lcd_ctrl omap1_lcd_ctrl;
 extern struct lcd_ctrl omap2_disp_ctrl;
 #endif
 
+extern void omapfb_reserve_sdram(void);
 extern void omapfb_register_panel(struct lcd_panel *panel);
 extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
 extern void omapfb_notify_clients(struct omapfb_device *fbdev,
index bfa09325a5ffad992a7c2aadd05b84d899ccf36d..768eb6e7abcfb719e83a3f085e3955e4b65d07fb 100644 (file)
  * Register and offset definitions to be used in PM assembler code
  * ----------------------------------------------------------------------------
  */
-#define CLKGEN_REG_ASM_BASE            io_p2v(0xfffece00)
+#define CLKGEN_REG_ASM_BASE            IO_ADDRESS(0xfffece00)
 #define ARM_IDLECT1_ASM_OFFSET         0x04
 #define ARM_IDLECT2_ASM_OFFSET         0x08
 
-#define TCMIF_ASM_BASE                 io_p2v(0xfffecc00)
+#define TCMIF_ASM_BASE                 IO_ADDRESS(0xfffecc00)
 #define EMIFS_CONFIG_ASM_OFFSET                0x0c
 #define EMIFF_SDRAM_CONFIG_ASM_OFFSET  0x20
 
@@ -135,7 +135,8 @@ extern void omap_pm_suspend(void);
 extern void omap730_cpu_suspend(unsigned short, unsigned short);
 extern void omap1510_cpu_suspend(unsigned short, unsigned short);
 extern void omap1610_cpu_suspend(unsigned short, unsigned short);
-extern void omap24xx_cpu_suspend(u32 dll_ctrl, u32 cpu_revision);
+extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
+                                       void __iomem *sdrc_power);
 extern void omap730_idle_loop_suspend(void);
 extern void omap1510_idle_loop_suspend(void);
 extern void omap1610_idle_loop_suspend(void);
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
new file mode 100644 (file)
index 0000000..2806a9c
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * OMAP2/3 powerdomain control
+ *
+ * Copyright (C) 2007-8 Texas Instruments, Inc.
+ * Copyright (C) 2007-8 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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_ARM_ARCH_OMAP_POWERDOMAIN
+#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <asm/atomic.h>
+
+#include <mach/cpu.h>
+
+
+/* Powerdomain basic power states */
+#define PWRDM_POWER_OFF                0x0
+#define PWRDM_POWER_RET                0x1
+#define PWRDM_POWER_INACTIVE   0x2
+#define PWRDM_POWER_ON         0x3
+
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_OFF_ON          ((1 << PWRDM_POWER_OFF) | \
+                                (1 << PWRDM_POWER_ON))
+
+#define PWRSTS_OFF_RET         ((1 << PWRDM_POWER_OFF) | \
+                                (1 << PWRDM_POWER_RET))
+
+#define PWRSTS_OFF_RET_ON      (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
+
+
+/* Powerdomain flags */
+#define PWRDM_HAS_HDWR_SAR     (1 << 0) /* hardware save-and-restore support */
+
+
+/*
+ * Number of memory banks that are power-controllable. On OMAP3430, the
+ * maximum is 4.
+ */
+#define PWRDM_MAX_MEM_BANKS    4
+
+/*
+ * Maximum number of clockdomains that can be associated with a powerdomain.
+ * CORE powerdomain is probably the worst case.
+ */
+#define PWRDM_MAX_CLKDMS       3
+
+/* XXX A completely arbitrary number. What is reasonable here? */
+#define PWRDM_TRANSITION_BAILOUT 100000
+
+struct clockdomain;
+struct powerdomain;
+
+/* Encodes dependencies between powerdomains - statically defined */
+struct pwrdm_dep {
+
+       /* Powerdomain name */
+       const char *pwrdm_name;
+
+       /* Powerdomain pointer - resolved by the powerdomain code */
+       struct powerdomain *pwrdm;
+
+       /* Flags to mark OMAP chip restrictions, etc. */
+       const struct omap_chip_id omap_chip;
+
+};
+
+struct powerdomain {
+
+       /* Powerdomain name */
+       const char *name;
+
+       /* the address offset from CM_BASE/PRM_BASE */
+       const s16 prcm_offs;
+
+       /* Used to represent the OMAP chip types containing this pwrdm */
+       const struct omap_chip_id omap_chip;
+
+       /* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
+       const u8 dep_bit;
+
+       /* Powerdomains that can be told to wake this powerdomain up */
+       struct pwrdm_dep *wkdep_srcs;
+
+       /* Powerdomains that can be told to keep this pwrdm from inactivity */
+       struct pwrdm_dep *sleepdep_srcs;
+
+       /* Possible powerdomain power states */
+       const u8 pwrsts;
+
+       /* Possible logic power states when pwrdm in RETENTION */
+       const u8 pwrsts_logic_ret;
+
+       /* Powerdomain flags */
+       const u8 flags;
+
+       /* Number of software-controllable memory banks in this powerdomain */
+       const u8 banks;
+
+       /* Possible memory bank pwrstates when pwrdm in RETENTION */
+       const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
+
+       /* Possible memory bank pwrstates when pwrdm is ON */
+       const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
+
+       /* Clockdomains in this powerdomain */
+       struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
+
+       struct list_head node;
+
+};
+
+
+void pwrdm_init(struct powerdomain **pwrdm_list);
+
+int pwrdm_register(struct powerdomain *pwrdm);
+int pwrdm_unregister(struct powerdomain *pwrdm);
+struct powerdomain *pwrdm_lookup(const char *name);
+
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm));
+
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+                        int (*fn)(struct powerdomain *pwrdm,
+                                  struct clockdomain *clkdm));
+
+int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
+
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
+
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
+
+int pwrdm_wait_transition(struct powerdomain *pwrdm);
+
+#endif
index 787b7acec546eeaf7330be8e8e834b83e5b22d61..a98c6c3beb2ce1a8d02a6f302a5323989381fe5d 100644 (file)
@@ -25,6 +25,8 @@
 #define SDRC_DLLB_STATUS       0x06C
 #define SDRC_POWER             0x070
 #define SDRC_MR_0              0x084
+#define SDRC_ACTIM_CTRL_A_0    0x09c
+#define SDRC_ACTIM_CTRL_B_0    0x0a0
 #define SDRC_RFR_CTRL_0                0x0a4
 
 /*
@@ -63,9 +65,9 @@
  */
 
 
-#define OMAP242X_SMS_REGADDR(reg)      (void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg)
-#define OMAP243X_SMS_REGADDR(reg)      (void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg)
-#define OMAP343X_SMS_REGADDR(reg)      (void __iomem *)IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+#define OMAP242X_SMS_REGADDR(reg)      IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+#define OMAP243X_SMS_REGADDR(reg)      IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+#define OMAP343X_SMS_REGADDR(reg)      IO_ADDRESS(OMAP343X_SMS_BASE + reg)
 
 /* SMS register offsets - read/write with sms_{read,write}_reg() */
 
index cc6bfa51ccb54022498cd8f02f1d68aa433467f0..8a676a04be481b1630cb7d0fa61cc87b00498aa4 100644 (file)
 #define OMAP_UART1_BASE                0x4806a000
 #define OMAP_UART2_BASE                0x4806c000
 #define OMAP_UART3_BASE                0x4806e000
+#elif defined(CONFIG_ARCH_OMAP3)
+/* OMAP3 serial ports */
+#define OMAP_UART1_BASE                0x4806a000
+#define OMAP_UART2_BASE                0x4806c000
+#define OMAP_UART3_BASE                0x49020000
 #endif
 
 #define OMAP_MAX_NR_PORTS      3
 #define OMAP1510_BASE_BAUD     (12000000/16)
 #define OMAP16XX_BASE_BAUD     (48000000/16)
+#define OMAP24XX_BASE_BAUD     (48000000/16)
 
-#define is_omap_port(p       ({int __ret = 0;                        \
-                       if (p == IO_ADDRESS(OMAP_UART1_BASE) || \
-                           p == IO_ADDRESS(OMAP_UART2_BASE) || \
-                           p == IO_ADDRESS(OMAP_UART3_BASE))   \
-                               __ret = 1;                      \
-                       __ret;                                  \
+#define is_omap_port(pt)       ({int __ret = 0;                        \
+                       if ((pt)->port.mapbase == OMAP_UART1_BASE ||    \
+                           (pt)->port.mapbase == OMAP_UART2_BASE ||    \
+                           (pt)->port.mapbase == OMAP_UART3_BASE)      \
+                               __ret = 1;                              \
+                       __ret;                                          \
                        })
 
 #endif
index e09323449981aa230f4b1a6e309d2117878cd548..ab35d622dcf5c4553c6340da777146c89f3b974b 100644 (file)
@@ -21,6 +21,10 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
                                      u32 mem_type);
 extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 
+extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
+                                    u32 sdrc_actim_ctrla,
+                                    u32 sdrc_actim_ctrlb, u32 m2);
+
 /* Do not use these */
 extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
 extern unsigned long omap1_sram_reprogram_clock_sz;
@@ -53,4 +57,10 @@ extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
                                                u32 mem_type);
 extern unsigned long omap243x_sram_reprogram_sdrc_sz;
 
+
+extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
+                                         u32 sdrc_actim_ctrla,
+                                         u32 sdrc_actim_ctrlb, u32 m2);
+extern unsigned long omap3_sram_configure_core_dpll_sz;
+
 #endif
index 06a28c7b98de7020054497fbfcb4714dec9ac321..06923f261545c268852f308ae73cb30b4546aa32 100644 (file)
@@ -40,7 +40,7 @@ static inline void omap1_arch_reset(char mode)
 
 static inline void arch_reset(char mode)
 {
-       if (!cpu_is_omap24xx())
+       if (!cpu_class_is_omap2())
                omap1_arch_reset(mode);
        else
                omap_prcm_arch_reset(mode);
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
new file mode 100644 (file)
index 0000000..af326ef
--- /dev/null
@@ -0,0 +1,107 @@
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
+#include <mach/omap730.h>
+#include <mach/omap1510.h>
+#include <mach/omap16xx.h>
+#include <mach/omap24xx.h>
+#include <mach/omap34xx.h>
+
+#define BETWEEN(p,st,sz)       ((p) >= (st) && (p) < ((st) + (sz)))
+#define XLATE(p,pst,vst)       ((void __iomem *)((p) - (pst) + (vst)))
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+#ifdef CONFIG_ARCH_OMAP1
+       if (cpu_class_is_omap1()) {
+               if (BETWEEN(p, IO_PHYS, IO_SIZE))
+                       return XLATE(p, IO_PHYS, IO_VIRT);
+       }
+       if (cpu_is_omap730()) {
+               if (BETWEEN(p, OMAP730_DSP_BASE, OMAP730_DSP_SIZE))
+                       return XLATE(p, OMAP730_DSP_BASE, OMAP730_DSP_START);
+
+               if (BETWEEN(p, OMAP730_DSPREG_BASE, OMAP730_DSPREG_SIZE))
+                       return XLATE(p, OMAP730_DSPREG_BASE,
+                                       OMAP730_DSPREG_START);
+       }
+       if (cpu_is_omap15xx()) {
+               if (BETWEEN(p, OMAP1510_DSP_BASE, OMAP1510_DSP_SIZE))
+                       return XLATE(p, OMAP1510_DSP_BASE, OMAP1510_DSP_START);
+
+               if (BETWEEN(p, OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_SIZE))
+                       return XLATE(p, OMAP1510_DSPREG_BASE,
+                                       OMAP1510_DSPREG_START);
+       }
+       if (cpu_is_omap16xx()) {
+               if (BETWEEN(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_SIZE))
+                       return XLATE(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_START);
+
+               if (BETWEEN(p, OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_SIZE))
+                       return XLATE(p, OMAP16XX_DSPREG_BASE,
+                                       OMAP16XX_DSPREG_START);
+       }
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+       if (cpu_is_omap24xx()) {
+               if (BETWEEN(p, L3_24XX_PHYS, L3_24XX_SIZE))
+                       return XLATE(p, L3_24XX_PHYS, L3_24XX_VIRT);
+               if (BETWEEN(p, L4_24XX_PHYS, L4_24XX_SIZE))
+                       return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT);
+       }
+       if (cpu_is_omap2420()) {
+               if (BETWEEN(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_SIZE))
+                       return XLATE(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_VIRT);
+               if (BETWEEN(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE))
+                       return XLATE(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE);
+               if (BETWEEN(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_SIZE))
+                       return XLATE(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_VIRT);
+       }
+       if (cpu_is_omap2430()) {
+               if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE))
+                       return XLATE(p, L4_WK_243X_PHYS, L4_WK_243X_VIRT);
+               if (BETWEEN(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_SIZE))
+                       return XLATE(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_VIRT);
+               if (BETWEEN(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_SIZE))
+                       return XLATE(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_VIRT);
+               if (BETWEEN(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_SIZE))
+                       return XLATE(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_VIRT);
+       }
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+       if (cpu_is_omap34xx()) {
+               if (BETWEEN(p, L3_34XX_PHYS, L3_34XX_SIZE))
+                       return XLATE(p, L3_34XX_PHYS, L3_34XX_VIRT);
+               if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE))
+                       return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT);
+               if (BETWEEN(p, L4_WK_34XX_PHYS, L4_WK_34XX_SIZE))
+                       return XLATE(p, L4_WK_34XX_PHYS, L4_WK_34XX_VIRT);
+               if (BETWEEN(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_SIZE))
+                       return XLATE(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_VIRT);
+               if (BETWEEN(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_SIZE))
+                       return XLATE(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_VIRT);
+               if (BETWEEN(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_SIZE))
+                       return XLATE(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_VIRT);
+               if (BETWEEN(p, L4_PER_34XX_PHYS, L4_PER_34XX_SIZE))
+                       return XLATE(p, L4_PER_34XX_PHYS, L4_PER_34XX_VIRT);
+               if (BETWEEN(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_SIZE))
+                       return XLATE(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_VIRT);
+       }
+#endif
+
+       return __arm_ioremap(p, size, type);
+}
+EXPORT_SYMBOL(omap_ioremap);
+
+void omap_iounmap(volatile void __iomem *addr)
+{
+       unsigned long virt = (unsigned long)addr;
+
+       if (virt >= VMALLOC_START && virt < VMALLOC_END)
+               __iounmap(addr);
+}
+EXPORT_SYMBOL(omap_iounmap);
index 014d26574bb61cd52267db7edfff9ad439e0c4bd..af33fc713e1a325d7e5179d8fa20921ebc1e152d 100644 (file)
 #include <mach/dma.h>
 #include <mach/mcbsp.h>
 
-static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
+struct omap_mcbsp **mcbsp_ptr;
+int omap_mcbsp_count;
 
-#define omap_mcbsp_check_valid_id(id)  (mcbsp[id].pdata && \
-                                       mcbsp[id].pdata->ops && \
-                                       mcbsp[id].pdata->ops->check && \
-                                       (mcbsp[id].pdata->ops->check(id) == 0))
+void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
+{
+       if (cpu_class_is_omap1() || cpu_is_omap2420())
+               __raw_writew((u16)val, io_base + reg);
+       else
+               __raw_writel(val, io_base + reg);
+}
+
+int omap_mcbsp_read(void __iomem *io_base, u16 reg)
+{
+       if (cpu_class_is_omap1() || cpu_is_omap2420())
+               return __raw_readw(io_base + reg);
+       else
+               return __raw_readl(io_base + reg);
+}
+
+#define OMAP_MCBSP_READ(base, reg) \
+                       omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg)
+#define OMAP_MCBSP_WRITE(base, reg, val) \
+                       omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val)
+
+#define omap_mcbsp_check_valid_id(id)  (id < omap_mcbsp_count)
+#define id_to_mcbsp_ptr(id)            mcbsp_ptr[id];
 
 static void omap_mcbsp_dump_reg(u8 id)
 {
-       dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);
-       dev_dbg(mcbsp[id].dev, "DRR2:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
-       dev_dbg(mcbsp[id].dev, "DRR1:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
-       dev_dbg(mcbsp[id].dev, "DXR2:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
-       dev_dbg(mcbsp[id].dev, "DXR1:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
-       dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
-       dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
-       dev_dbg(mcbsp[id].dev, "RCR2:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
-       dev_dbg(mcbsp[id].dev, "RCR1:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
-       dev_dbg(mcbsp[id].dev, "XCR2:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
-       dev_dbg(mcbsp[id].dev, "XCR1:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
-       dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
-       dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
-       dev_dbg(mcbsp[id].dev, "PCR0:  0x%04x\n",
-                       OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
-       dev_dbg(mcbsp[id].dev, "***********************\n");
+       struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
+
+       dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
+       dev_dbg(mcbsp->dev, "DRR2:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
+       dev_dbg(mcbsp->dev, "DRR1:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
+       dev_dbg(mcbsp->dev, "DXR2:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
+       dev_dbg(mcbsp->dev, "DXR1:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
+       dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
+       dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
+       dev_dbg(mcbsp->dev, "RCR2:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
+       dev_dbg(mcbsp->dev, "RCR1:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
+       dev_dbg(mcbsp->dev, "XCR2:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
+       dev_dbg(mcbsp->dev, "XCR1:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
+       dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
+       dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
+       dev_dbg(mcbsp->dev, "PCR0:  0x%04x\n",
+                       OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
+       dev_dbg(mcbsp->dev, "***********************\n");
 }
 
 static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
@@ -126,16 +148,18 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
  */
 void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
 {
-       u32 io_base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *io_base;
 
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       io_base = mcbsp[id].io_base;
-       dev_dbg(mcbsp[id].dev, "Configuring McBSP%d  io_base: 0x%8x\n",
-                       mcbsp[id].id, io_base);
+       io_base = mcbsp->io_base;
+       dev_dbg(mcbsp->dev, "Configuring McBSP%d  phys_base: 0x%08lx\n",
+                       mcbsp->id, mcbsp->phys_base);
 
        /* We write the given config */
        OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
@@ -158,23 +182,26 @@ EXPORT_SYMBOL(omap_mcbsp_config);
  */
 int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
 {
+       struct omap_mcbsp *mcbsp;
+
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       spin_lock(&mcbsp[id].lock);
+       spin_lock(&mcbsp->lock);
 
-       if (!mcbsp[id].free) {
-               dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
-                       mcbsp[id].id);
-               spin_unlock(&mcbsp[id].lock);
+       if (!mcbsp->free) {
+               dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
+                       mcbsp->id);
+               spin_unlock(&mcbsp->lock);
                return -EINVAL;
        }
 
-       mcbsp[id].io_type = io_type;
+       mcbsp->io_type = io_type;
 
-       spin_unlock(&mcbsp[id].lock);
+       spin_unlock(&mcbsp->lock);
 
        return 0;
 }
@@ -182,53 +209,60 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
 
 int omap_mcbsp_request(unsigned int id)
 {
+       struct omap_mcbsp *mcbsp;
        int err;
 
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       if (mcbsp[id].pdata->ops->request)
-               mcbsp[id].pdata->ops->request(id);
+       if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
+               mcbsp->pdata->ops->request(id);
 
-       clk_enable(mcbsp[id].clk);
+       clk_enable(mcbsp->clk);
 
-       spin_lock(&mcbsp[id].lock);
-       if (!mcbsp[id].free) {
-               dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
-                       mcbsp[id].id);
-               spin_unlock(&mcbsp[id].lock);
+       spin_lock(&mcbsp->lock);
+       if (!mcbsp->free) {
+               dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
+                       mcbsp->id);
+               spin_unlock(&mcbsp->lock);
                return -1;
        }
 
-       mcbsp[id].free = 0;
-       spin_unlock(&mcbsp[id].lock);
+       mcbsp->free = 0;
+       spin_unlock(&mcbsp->lock);
+
+       /*
+        * Make sure that transmitter, receiver and sample-rate generator are
+        * not running before activating IRQs.
+        */
+       OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0);
+       OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0);
 
-       if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
+       if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
                /* We need to get IRQs here */
-               err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,
-                                       0, "McBSP", (void *) (&mcbsp[id]));
+               init_completion(&mcbsp->tx_irq_completion);
+               err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
+                                       0, "McBSP", (void *)mcbsp);
                if (err != 0) {
-                       dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "
-                                       "for McBSP%d\n", mcbsp[id].tx_irq,
-                                       mcbsp[id].id);
+                       dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
+                                       "for McBSP%d\n", mcbsp->tx_irq,
+                                       mcbsp->id);
                        return err;
                }
 
-               init_completion(&(mcbsp[id].tx_irq_completion));
-
-               err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,
-                                       0, "McBSP", (void *) (&mcbsp[id]));
+               init_completion(&mcbsp->rx_irq_completion);
+               err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler,
+                                       0, "McBSP", (void *)mcbsp);
                if (err != 0) {
-                       dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "
-                                       "for McBSP%d\n", mcbsp[id].rx_irq,
-                                       mcbsp[id].id);
-                       free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+                       dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
+                                       "for McBSP%d\n", mcbsp->rx_irq,
+                                       mcbsp->id);
+                       free_irq(mcbsp->tx_irq, (void *)mcbsp);
                        return err;
                }
-
-               init_completion(&(mcbsp[id].rx_irq_completion));
        }
 
        return 0;
@@ -237,31 +271,34 @@ EXPORT_SYMBOL(omap_mcbsp_request);
 
 void omap_mcbsp_free(unsigned int id)
 {
+       struct omap_mcbsp *mcbsp;
+
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       if (mcbsp[id].pdata->ops->free)
-               mcbsp[id].pdata->ops->free(id);
+       if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
+               mcbsp->pdata->ops->free(id);
 
-       clk_disable(mcbsp[id].clk);
+       clk_disable(mcbsp->clk);
 
-       spin_lock(&mcbsp[id].lock);
-       if (mcbsp[id].free) {
-               dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",
-                       mcbsp[id].id);
-               spin_unlock(&mcbsp[id].lock);
+       spin_lock(&mcbsp->lock);
+       if (mcbsp->free) {
+               dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
+                       mcbsp->id);
+               spin_unlock(&mcbsp->lock);
                return;
        }
 
-       mcbsp[id].free = 1;
-       spin_unlock(&mcbsp[id].lock);
+       mcbsp->free = 1;
+       spin_unlock(&mcbsp->lock);
 
-       if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
+       if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
                /* Free IRQs */
-               free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
-               free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+               free_irq(mcbsp->rx_irq, (void *)mcbsp);
+               free_irq(mcbsp->tx_irq, (void *)mcbsp);
        }
 }
 EXPORT_SYMBOL(omap_mcbsp_free);
@@ -273,18 +310,19 @@ EXPORT_SYMBOL(omap_mcbsp_free);
  */
 void omap_mcbsp_start(unsigned int id)
 {
-       u32 io_base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *io_base;
        u16 w;
 
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
+       io_base = mcbsp->io_base;
 
-       io_base = mcbsp[id].io_base;
-
-       mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
-       mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
+       mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
+       mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
 
        /* Start the sample generator */
        w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -310,7 +348,8 @@ EXPORT_SYMBOL(omap_mcbsp_start);
 
 void omap_mcbsp_stop(unsigned int id)
 {
-       u32 io_base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *io_base;
        u16 w;
 
        if (!omap_mcbsp_check_valid_id(id)) {
@@ -318,7 +357,8 @@ void omap_mcbsp_stop(unsigned int id)
                return;
        }
 
-       io_base = mcbsp[id].io_base;
+       mcbsp = id_to_mcbsp_ptr(id);
+       io_base = mcbsp->io_base;
 
        /* Reset transmitter */
        w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -337,14 +377,17 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
 /* polled mcbsp i/o operations */
 int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
 {
-       u32 base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *base;
 
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
 
-       base = mcbsp[id].io_base;
+       mcbsp = id_to_mcbsp_ptr(id);
+       base = mcbsp->io_base;
+
        writew(buf, base + OMAP_MCBSP_REG_DXR1);
        /* if frame sync error - clear the error */
        if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
@@ -366,8 +409,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
                                       (XRST),
                                       base + OMAP_MCBSP_REG_SPCR2);
                                udelay(10);
-                               dev_err(mcbsp[id].dev, "Could not write to"
-                                       " McBSP%d Register\n", mcbsp[id].id);
+                               dev_err(mcbsp->dev, "Could not write to"
+                                       " McBSP%d Register\n", mcbsp->id);
                                return -2;
                        }
                }
@@ -379,14 +422,16 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
 
 int omap_mcbsp_pollread(unsigned int id, u16 *buf)
 {
-       u32 base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *base;
 
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       base = mcbsp[id].io_base;
+       base = mcbsp->io_base;
        /* if frame sync error - clear the error */
        if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
                /* clear error */
@@ -407,8 +452,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
                                       (RRST),
                                       base + OMAP_MCBSP_REG_SPCR1);
                                udelay(10);
-                               dev_err(mcbsp[id].dev, "Could not read from"
-                                       " McBSP%d Register\n", mcbsp[id].id);
+                               dev_err(mcbsp->dev, "Could not read from"
+                                       " McBSP%d Register\n", mcbsp->id);
                                return -2;
                        }
                }
@@ -424,7 +469,8 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
  */
 void omap_mcbsp_xmit_word(unsigned int id, u32 word)
 {
-       u32 io_base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *io_base;
        omap_mcbsp_word_length word_length;
 
        if (!omap_mcbsp_check_valid_id(id)) {
@@ -432,10 +478,11 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
                return;
        }
 
-       io_base = mcbsp[id].io_base;
-       word_length = mcbsp[id].tx_word_length;
+       mcbsp = id_to_mcbsp_ptr(id);
+       io_base = mcbsp->io_base;
+       word_length = mcbsp->tx_word_length;
 
-       wait_for_completion(&(mcbsp[id].tx_irq_completion));
+       wait_for_completion(&mcbsp->tx_irq_completion);
 
        if (word_length > OMAP_MCBSP_WORD_16)
                OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
@@ -445,7 +492,8 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word);
 
 u32 omap_mcbsp_recv_word(unsigned int id)
 {
-       u32 io_base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *io_base;
        u16 word_lsb, word_msb = 0;
        omap_mcbsp_word_length word_length;
 
@@ -453,11 +501,12 @@ u32 omap_mcbsp_recv_word(unsigned int id)
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       word_length = mcbsp[id].rx_word_length;
-       io_base = mcbsp[id].io_base;
+       word_length = mcbsp->rx_word_length;
+       io_base = mcbsp->io_base;
 
-       wait_for_completion(&(mcbsp[id].rx_irq_completion));
+       wait_for_completion(&mcbsp->rx_irq_completion);
 
        if (word_length > OMAP_MCBSP_WORD_16)
                word_msb = OMAP_MCBSP_READ(io_base, DRR2);
@@ -469,7 +518,8 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
 
 int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
 {
-       u32 io_base;
+       struct omap_mcbsp *mcbsp;
+       void __iomem *io_base;
        omap_mcbsp_word_length tx_word_length;
        omap_mcbsp_word_length rx_word_length;
        u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -478,10 +528,10 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
-
-       io_base = mcbsp[id].io_base;
-       tx_word_length = mcbsp[id].tx_word_length;
-       rx_word_length = mcbsp[id].rx_word_length;
+       mcbsp = id_to_mcbsp_ptr(id);
+       io_base = mcbsp->io_base;
+       tx_word_length = mcbsp->tx_word_length;
+       rx_word_length = mcbsp->rx_word_length;
 
        if (tx_word_length != rx_word_length)
                return -EINVAL;
@@ -496,8 +546,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
                        udelay(10);
                        OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
                        udelay(10);
-                       dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
-                               "ready\n", mcbsp[id].id);
+                       dev_err(mcbsp->dev, "McBSP%d transmitter not "
+                               "ready\n", mcbsp->id);
                        return -EAGAIN;
                }
        }
@@ -517,8 +567,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
                        udelay(10);
                        OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
                        udelay(10);
-                       dev_err(mcbsp[id].dev, "McBSP%d receiver not "
-                               "ready\n", mcbsp[id].id);
+                       dev_err(mcbsp->dev, "McBSP%d receiver not "
+                               "ready\n", mcbsp->id);
                        return -EAGAIN;
                }
        }
@@ -534,7 +584,9 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
 
 int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
 {
-       u32 io_base, clock_word = 0;
+       struct omap_mcbsp *mcbsp;
+       u32 clock_word = 0;
+       void __iomem *io_base;
        omap_mcbsp_word_length tx_word_length;
        omap_mcbsp_word_length rx_word_length;
        u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -544,9 +596,11 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
                return -ENODEV;
        }
 
-       io_base = mcbsp[id].io_base;
-       tx_word_length = mcbsp[id].tx_word_length;
-       rx_word_length = mcbsp[id].rx_word_length;
+       mcbsp = id_to_mcbsp_ptr(id);
+       io_base = mcbsp->io_base;
+
+       tx_word_length = mcbsp->tx_word_length;
+       rx_word_length = mcbsp->rx_word_length;
 
        if (tx_word_length != rx_word_length)
                return -EINVAL;
@@ -561,8 +615,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
                        udelay(10);
                        OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
                        udelay(10);
-                       dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
-                               "ready\n", mcbsp[id].id);
+                       dev_err(mcbsp->dev, "McBSP%d transmitter not "
+                               "ready\n", mcbsp->id);
                        return -EAGAIN;
                }
        }
@@ -582,8 +636,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
                        udelay(10);
                        OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
                        udelay(10);
-                       dev_err(mcbsp[id].dev, "McBSP%d receiver not "
-                               "ready\n", mcbsp[id].id);
+                       dev_err(mcbsp->dev, "McBSP%d receiver not "
+                               "ready\n", mcbsp->id);
                        return -EAGAIN;
                }
        }
@@ -609,6 +663,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
 int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
                                unsigned int length)
 {
+       struct omap_mcbsp *mcbsp;
        int dma_tx_ch;
        int src_port = 0;
        int dest_port = 0;
@@ -618,50 +673,51 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",
+       if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
                                omap_mcbsp_tx_dma_callback,
-                               &mcbsp[id],
+                               mcbsp,
                                &dma_tx_ch)) {
-               dev_err(mcbsp[id].dev, " Unable to request DMA channel for "
+               dev_err(mcbsp->dev, " Unable to request DMA channel for "
                                "McBSP%d TX. Trying IRQ based TX\n",
-                               mcbsp[id].id);
+                               mcbsp->id);
                return -EAGAIN;
        }
-       mcbsp[id].dma_tx_lch = dma_tx_ch;
+       mcbsp->dma_tx_lch = dma_tx_ch;
 
-       dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,
+       dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
                dma_tx_ch);
 
-       init_completion(&(mcbsp[id].tx_dma_completion));
+       init_completion(&mcbsp->tx_dma_completion);
 
        if (cpu_class_is_omap1()) {
                src_port = OMAP_DMA_PORT_TIPB;
                dest_port = OMAP_DMA_PORT_EMIFF;
        }
        if (cpu_class_is_omap2())
-               sync_dev = mcbsp[id].dma_tx_sync;
+               sync_dev = mcbsp->dma_tx_sync;
 
-       omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
+       omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
                                     OMAP_DMA_DATA_TYPE_S16,
                                     length >> 1, 1,
                                     OMAP_DMA_SYNC_ELEMENT,
         sync_dev, 0);
 
-       omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
+       omap_set_dma_dest_params(mcbsp->dma_tx_lch,
                                 src_port,
                                 OMAP_DMA_AMODE_CONSTANT,
-                                mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1,
+                                mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
                                 0, 0);
 
-       omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
+       omap_set_dma_src_params(mcbsp->dma_tx_lch,
                                dest_port,
                                OMAP_DMA_AMODE_POST_INC,
                                buffer,
                                0, 0);
 
-       omap_start_dma(mcbsp[id].dma_tx_lch);
-       wait_for_completion(&(mcbsp[id].tx_dma_completion));
+       omap_start_dma(mcbsp->dma_tx_lch);
+       wait_for_completion(&mcbsp->tx_dma_completion);
 
        return 0;
 }
@@ -670,6 +726,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
 int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
                                unsigned int length)
 {
+       struct omap_mcbsp *mcbsp;
        int dma_rx_ch;
        int src_port = 0;
        int dest_port = 0;
@@ -679,50 +736,51 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return -ENODEV;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
-       if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",
+       if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
                                omap_mcbsp_rx_dma_callback,
-                               &mcbsp[id],
+                               mcbsp,
                                &dma_rx_ch)) {
-               dev_err(mcbsp[id].dev, "Unable to request DMA channel for "
+               dev_err(mcbsp->dev, "Unable to request DMA channel for "
                                "McBSP%d RX. Trying IRQ based RX\n",
-                               mcbsp[id].id);
+                               mcbsp->id);
                return -EAGAIN;
        }
-       mcbsp[id].dma_rx_lch = dma_rx_ch;
+       mcbsp->dma_rx_lch = dma_rx_ch;
 
-       dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,
+       dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
                dma_rx_ch);
 
-       init_completion(&(mcbsp[id].rx_dma_completion));
+       init_completion(&mcbsp->rx_dma_completion);
 
        if (cpu_class_is_omap1()) {
                src_port = OMAP_DMA_PORT_TIPB;
                dest_port = OMAP_DMA_PORT_EMIFF;
        }
        if (cpu_class_is_omap2())
-               sync_dev = mcbsp[id].dma_rx_sync;
+               sync_dev = mcbsp->dma_rx_sync;
 
-       omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
+       omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
                                        OMAP_DMA_DATA_TYPE_S16,
                                        length >> 1, 1,
                                        OMAP_DMA_SYNC_ELEMENT,
                                        sync_dev, 0);
 
-       omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
+       omap_set_dma_src_params(mcbsp->dma_rx_lch,
                                src_port,
                                OMAP_DMA_AMODE_CONSTANT,
-                               mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1,
+                               mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
                                0, 0);
 
-       omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
+       omap_set_dma_dest_params(mcbsp->dma_rx_lch,
                                        dest_port,
                                        OMAP_DMA_AMODE_POST_INC,
                                        buffer,
                                        0, 0);
 
-       omap_start_dma(mcbsp[id].dma_rx_lch);
-       wait_for_completion(&(mcbsp[id].rx_dma_completion));
+       omap_start_dma(mcbsp->dma_rx_lch);
+       wait_for_completion(&mcbsp->rx_dma_completion);
 
        return 0;
 }
@@ -737,12 +795,14 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
 void omap_mcbsp_set_spi_mode(unsigned int id,
                                const struct omap_mcbsp_spi_cfg *spi_cfg)
 {
+       struct omap_mcbsp *mcbsp;
        struct omap_mcbsp_reg_cfg mcbsp_cfg;
 
        if (!omap_mcbsp_check_valid_id(id)) {
                printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
                return;
        }
+       mcbsp = id_to_mcbsp_ptr(id);
 
        memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
 
@@ -803,9 +863,10 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
  * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
  * 730 has only 2 McBSP, and both of them are MPU peripherals.
  */
-static int __init omap_mcbsp_probe(struct platform_device *pdev)
+static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 {
        struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
+       struct omap_mcbsp *mcbsp;
        int id = pdev->id - 1;
        int ret = 0;
 
@@ -818,47 +879,63 @@ static int __init omap_mcbsp_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
 
-       if (id >= OMAP_MAX_MCBSP_COUNT) {
+       if (id >= omap_mcbsp_count) {
                dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
                ret = -EINVAL;
                goto exit;
        }
 
-       spin_lock_init(&mcbsp[id].lock);
-       mcbsp[id].id = id + 1;
-       mcbsp[id].free = 1;
-       mcbsp[id].dma_tx_lch = -1;
-       mcbsp[id].dma_rx_lch = -1;
+       mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
+       if (!mcbsp) {
+               ret = -ENOMEM;
+               goto exit;
+       }
+       mcbsp_ptr[id] = mcbsp;
+
+       spin_lock_init(&mcbsp->lock);
+       mcbsp->id = id + 1;
+       mcbsp->free = 1;
+       mcbsp->dma_tx_lch = -1;
+       mcbsp->dma_rx_lch = -1;
+
+       mcbsp->phys_base = pdata->phys_base;
+       mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+       if (!mcbsp->io_base) {
+               ret = -ENOMEM;
+               goto err_ioremap;
+       }
 
-       mcbsp[id].phys_base = pdata->phys_base;
-       mcbsp[id].io_base = pdata->virt_base;
        /* Default I/O is IRQ based */
-       mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;
-       mcbsp[id].tx_irq = pdata->tx_irq;
-       mcbsp[id].rx_irq = pdata->rx_irq;
-       mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;
-       mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;
+       mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
+       mcbsp->tx_irq = pdata->tx_irq;
+       mcbsp->rx_irq = pdata->rx_irq;
+       mcbsp->dma_rx_sync = pdata->dma_rx_sync;
+       mcbsp->dma_tx_sync = pdata->dma_tx_sync;
 
        if (pdata->clk_name)
-               mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name);
-       if (IS_ERR(mcbsp[id].clk)) {
-               mcbsp[id].free = 0;
+               mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name);
+       if (IS_ERR(mcbsp->clk)) {
                dev_err(&pdev->dev,
                        "Invalid clock configuration for McBSP%d.\n",
-                       mcbsp[id].id);
-               ret = -EINVAL;
-               goto exit;
+                       mcbsp->id);
+               ret = PTR_ERR(mcbsp->clk);
+               goto err_clk;
        }
 
-       mcbsp[id].pdata = pdata;
-       mcbsp[id].dev = &pdev->dev;
-       platform_set_drvdata(pdev, &mcbsp[id]);
+       mcbsp->pdata = pdata;
+       mcbsp->dev = &pdev->dev;
+       platform_set_drvdata(pdev, mcbsp);
+       return 0;
 
+err_clk:
+       iounmap(mcbsp->io_base);
+err_ioremap:
+       mcbsp->free = 0;
 exit:
        return ret;
 }
 
-static int omap_mcbsp_remove(struct platform_device *pdev)
+static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
 {
        struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
 
@@ -872,6 +949,8 @@ static int omap_mcbsp_remove(struct platform_device *pdev)
                clk_disable(mcbsp->clk);
                clk_put(mcbsp->clk);
 
+               iounmap(mcbsp->io_base);
+
                mcbsp->clk = NULL;
                mcbsp->free = 0;
                mcbsp->dev = NULL;
@@ -882,7 +961,7 @@ static int omap_mcbsp_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_mcbsp_driver = {
        .probe          = omap_mcbsp_probe,
-       .remove         = omap_mcbsp_remove,
+       .remove         = __devexit_p(omap_mcbsp_remove),
        .driver         = {
                .name   = "omap-mcbsp",
        },
index e0003e0746e748076c47ca95e0bf9ec775b1d87d..9f9a921829c00686f5b8a658c89bef8e084558d0 100644 (file)
@@ -271,7 +271,7 @@ int __init omap1_sram_init(void)
 #define omap1_sram_init()      do {} while (0)
 #endif
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+#if defined(CONFIG_ARCH_OMAP2)
 
 static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
                              u32 base_cs, u32 force_unlock);
@@ -352,23 +352,19 @@ static inline int omap243x_sram_init(void)
 
 #ifdef CONFIG_ARCH_OMAP3
 
-static u32 (*_omap2_sram_reprogram_gpmc)(u32 perf_level);
-u32 omap2_sram_reprogram_gpmc(u32 perf_level)
-{
-       if (!_omap2_sram_reprogram_gpmc)
-               omap_sram_error();
-
-       return _omap2_sram_reprogram_gpmc(perf_level);
-}
-
-static u32 (*_omap2_sram_configure_core_dpll)(u32 m, u32 n,
-                                               u32 freqsel, u32 m2);
-u32 omap2_sram_configure_core_dpll(u32 m, u32 n, u32 freqsel, u32 m2)
+static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
+                                             u32 sdrc_actim_ctrla,
+                                             u32 sdrc_actim_ctrlb,
+                                             u32 m2);
+u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
+                             u32 sdrc_actim_ctrlb, u32 m2)
 {
-       if (!_omap2_sram_configure_core_dpll)
+       if (!_omap3_sram_configure_core_dpll)
                omap_sram_error();
 
-       return _omap2_sram_configure_core_dpll(m, n, freqsel, m2);
+       return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
+                                              sdrc_actim_ctrla,
+                                              sdrc_actim_ctrlb, m2);
 }
 
 /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
@@ -376,31 +372,16 @@ void restore_sram_functions(void)
 {
        omap_sram_ceil = omap_sram_base + omap_sram_size;
 
-       _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc,
-               omap34xx_sram_reprogram_gpmc_sz);
-
-       _omap2_sram_configure_core_dpll =
-                       omap_sram_push(omap34xx_sram_configure_core_dpll,
-                                       omap34xx_sram_configure_core_dpll_sz);
+       _omap3_sram_configure_core_dpll =
+               omap_sram_push(omap3_sram_configure_core_dpll,
+                              omap3_sram_configure_core_dpll_sz);
 }
 
 int __init omap34xx_sram_init(void)
 {
-       _omap2_sram_ddr_init = omap_sram_push(omap34xx_sram_ddr_init,
-                                       omap34xx_sram_ddr_init_sz);
-
-       _omap2_sram_reprogram_sdrc = omap_sram_push(omap34xx_sram_reprogram_sdrc,
-                                       omap34xx_sram_reprogram_sdrc_sz);
-
-       _omap2_set_prcm = omap_sram_push(omap34xx_sram_set_prcm,
-                                       omap34xx_sram_set_prcm_sz);
-
-       _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc,
-                                       omap34xx_sram_reprogram_gpmc_sz);
-
-       _omap2_sram_configure_core_dpll =
-                               omap_sram_push(omap34xx_sram_configure_core_dpll,
-                                       omap34xx_sram_configure_core_dpll_sz);
+       _omap3_sram_configure_core_dpll =
+               omap_sram_push(omap3_sram_configure_core_dpll,
+                              omap3_sram_configure_core_dpll_sz);
 
        return 0;
 }
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
new file mode 100644 (file)
index 0000000..f03d7b3
--- /dev/null
@@ -0,0 +1,3 @@
+# dummy makefile, currently just including asm/arm/plat-s3c/include/plat
+
+obj-n  := dummy.o
similarity index 97%
rename from include/asm-arm/plat-s3c/debug-macro.S
rename to arch/arm/plat-s3c/include/plat/debug-macro.S
index 84c40b847da8c2ef26ce4eaabade0d7a56239eec..4aa7e2e6c001a1f55624fdfcb612fa43a96ac405 100644 (file)
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
 */
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
 /* The S3C2440 implementations are used by default as they are the
  * most widely re-used */
similarity index 98%
rename from include/asm-arm/plat-s3c/uncompress.h
rename to arch/arm/plat-s3c/include/plat/uncompress.h
index 19b9eda39485191ac13405ce02b8e0531f997ae1..4df006b9cc1053199d59fe348bdbca61fde624f4 100644 (file)
@@ -27,7 +27,7 @@ static void arch_detect_cpu(void);
 
 /* defines for UART registers */
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <asm/plat-s3c/regs-watchdog.h>
 
 /* working in physical space... */
index 400541359bfbc617d0b569c8197c6fdfc2e76b90..a005ddbd9ef3b00f16ac1a5668bc19889c4614ea 100644 (file)
@@ -47,8 +47,8 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 /* clock information */
 
index d528f460f6bc48027a6155a4084adb9d079ff63e..3098736c65d99d3bdc90ec83f1ff0c49cd5afd41 100644 (file)
@@ -40,9 +40,9 @@
 
 #include <asm/plat-s3c/nand.h>
 
-#include <asm/plat-s3c24xx/common-smdk.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/common-smdk.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
 
 /* LED devices */
 
index 9c607bbc9343bc34712536a66cd2a30b9d4ce556..22a329513c0f3ff0149791066ae4d6a5c64515c1 100644 (file)
 #include <mach/system-reset.h>
 
 #include <mach/regs-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
-
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/s3c2400.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s3c2400.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
 #include "s3c244x.h"
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/s3c2442.h>
-#include <asm/plat-s3c24xx/s3c2443.h>
+#include <plat/s3c2440.h>
+#include <plat/s3c2442.h>
+#include <plat/s3c2443.h>
 
 struct cpu_table {
        unsigned long   idcode;
index 6b13b5455dfc6b32935da3d3bcac491a9e284f2e..e93f8bf6d3386659e175e1248adfea8178982bf4 100644 (file)
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <asm/plat-s3c24xx/udc.h>
 
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
 #include <asm/plat-s3c24xx/regs-spi.h>
 
 /* Serial port registrations */
index d6344461a83bb13494e41c72f9667de66ee3a47b..1baf941d1930b76e94b58b23464e5d71da00ab8d 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/mach/dma.h>
 #include <mach/map.h>
 
-#include <asm/plat-s3c24xx/dma.h>
+#include <plat/dma.h>
 
 /* io map for dma */
 static void __iomem *dma_base;
index 590fc5a3ab06e8710b295a7cc5cdc80959654c98..963f7a4f26f23042611426f4e9245337764b566a 100644 (file)
@@ -65,9 +65,9 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
 
 /* wakeup irq control */
 
index 0a074d35890aa5eebc76eb9d1bf6fea4ef537700..21dfa74773d17ec0d61109fbd47ce1a4477f9211 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <asm/mach-types.h>
 
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/pm.h>
 
 #define COPYRIGHT ", (c) 2005 Simtec Electronics"
 
index d3934b1119a9e0c855f3e16153c6bad696f26144..8efb57ad501948974b0400c3f5ed75910506575d 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/cacheflush.h>
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-mem.h>
@@ -48,7 +48,7 @@
 
 #include <asm/mach/time.h>
 
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/pm.h>
 
 /* for external use */
 
index 306cc9c6f9efebf44258a24d956197fd9f63b3a7..b8e854f1b1d50dbc4f7524b2b9843ed614f51a4b 100644 (file)
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
-#include <asm/plat-s3c/regs-timer.h>
+#include <plat/regs-timer.h>
 
 /* Each of the timers 0 through 5 go through the following
  * clock tree, with the inputs depending on the timers.
index 7a92c938542a6e4e59b652eca8d2f3287164a37e..feb770f2e84e1a470bcd3cc1b4e57686e10f0171 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/io.h>
 #include <linux/pwm.h>
 
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c/regs-timer.h>
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
 
 struct pwm_device {
        struct list_head         list;
index 119647a5eaa63e8db78eff5c8f2a2dccf9ddd99d..7c09773ff9fcdfe93b48c64707035206f9b48f2f 100644 (file)
@@ -41,8 +41,8 @@
 
 #include <mach/regs-clock.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
 {
index 0601c5f3230bdd84700aa3b4b4e93568afb71422..0902afd227cadf8b690285cb9d7e5c1ac0eec912 100644 (file)
@@ -34,9 +34,9 @@
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
 
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
 
 /* camera irq */
 
index 146863a69aeb3fae4a611c2abbfc1ab6d43aa96d..c0344fac4a9492706609ed7ef5a2a42a4b27c9b0 100644 (file)
 #include <asm/irq.h>
 
 #include <mach/regs-clock.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-gpioj.h>
 #include <mach/regs-dsc.h>
 
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
 #include "s3c244x.h"
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
 
 static struct map_desc s3c244x_iodesc[] __initdata = {
        IODESC_ENT(CLKPWR),
index 4981a08b6ebbcb9fa6eb5e604b2f453b1ec18699..76594b21280258e4fa05d21190030599f27dd8a4 100644 (file)
@@ -32,7 +32,7 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-mem.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 
 /* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
  * reset the UART configuration, only enable if you really need this!
index 64bfa19ae951c1444d8741835ef49d12f1f27432..c51916236ac082bfad855f9ecc6d93588a9fbdc1 100644 (file)
 
 #include <asm/irq.h>
 #include <mach/map.h>
-#include <asm/plat-s3c/regs-timer.h>
+#include <plat/regs-timer.h>
 #include <mach/regs-irq.h>
 #include <asm/mach/time.h>
 
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
 
 static unsigned long timer_startval;
 static unsigned long timer_usec_ticks;
index 64ce40ee1d585d052e437d4f8ada3026e200bcfb..d5d1d41c600a81e6eea29bd07967fa2412ffce14 100644 (file)
@@ -103,6 +103,6 @@ typedef struct user_fpu_struct elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
 
 #endif /* __ASM_AVR32_ELF_H */
index 5dd8d25428bfb7d6a48a084eee1d114d83efaeeb..d84efe4984ab82da6aaae2a6ca2c09d700016c80 100644 (file)
@@ -87,7 +87,6 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
        policy->cur = at32_get_speed(0);
        policy->min = policy->cpuinfo.min_freq;
        policy->max = policy->cpuinfo.max_freq;
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 
        printk("cpufreq: AT32AP CPU frequency driver\n");
 
index c33bf6f83813fd09b05d01704b708439c2721668..4443a47e516f8e38d011f17198af562e3bc4aae4 100644 (file)
@@ -748,7 +748,7 @@ CONFIG_BFIN_OTP=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
index 66854a83c0de648c8b7ad6cf6a36801d9f38d666..4a2a660a6b3578260f579234e23521377182a52d 100644 (file)
@@ -772,7 +772,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
index 6bc11db12690b49077dc5b359dbd99d528494263..deeb5e45effbdda40dfc6682c9c6d60ffa7b4657 100644 (file)
@@ -674,7 +674,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -740,7 +740,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index d77d991a1f619877e1ea25ddf32ebad9f10fcf8e..c23267ed880bde1514e5f00b325f40b1bb794d90 100644 (file)
@@ -681,7 +681,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
index 5fd7c4b143df56bfd3f7bb8b3fed4a75e025ab1c..63a0f854745cc740ce8f76ece096e5f52b8a86ee 100644 (file)
@@ -731,7 +731,7 @@ CONFIG_CAN4LINUX=y
 # CONFIG_CAN_UNCTWINCAN is not set
 CONFIG_CAN_BLACKFIN=m
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -871,7 +871,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index 390669e8668e0695fb41da67baf77bcbe205410d..bf63660815b927de3a2a496a131d1ac1d7bac43f 100644 (file)
@@ -855,7 +855,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1001,7 +1001,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 # CONFIG_USB_DABUSB is not set
 
 #
index 976a4d7ba175ee955270d9170023d02525d3a19b..3c70d6230a12fe28ff25383ec174041fb2eef942 100644 (file)
@@ -719,7 +719,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -785,7 +785,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index 0799aa9bba9d430187cffc1b850758928540273d..b6a14635fb91f844867e01bc3dad3feac327cc31 100644 (file)
@@ -679,7 +679,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
index 09deea44480b43d6d830d19d2c8c317625a7b40f..c3ba9066b935a651662bb346090d135e789eef61 100644 (file)
@@ -672,7 +672,7 @@ CONFIG_HWMON=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index 219fc345a5f5bdc7f2a25273cc4ace45c25e29c9..cdc6b7feb59eb14e67540b2dd6f0d3f4f0e74fe9 100644 (file)
@@ -703,7 +703,7 @@ CONFIG_HWMON=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index 9873d586fc7753240a01d774b9d9e165f9a3b146..f074bdcd1ce589b6852a8352dea2491cf708fb9b 100644 (file)
@@ -683,7 +683,7 @@ CONFIG_HWMON=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index 0e3605fdb7b040f8c8be5038fa43a3d5ade884f5..5c44fdb8e6e363bdf65fb3daf89581662438c498 100644 (file)
@@ -762,7 +762,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -909,7 +909,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 # CONFIG_USB_DABUSB is not set
 
 #
index 59c7cdbee904f0206755731174193799d1130ef2..086fe5dda4950e8296ddf2ed972ef9238d6fa70b 100644 (file)
@@ -684,7 +684,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 
 #
 # Graphics support
index 5ef9e35e9c3bce6b1444200320648166fca5f04d..4403415583fa67f8809e3e14399e8c648b72562a 100644 (file)
 #ifndef _BLACKFIN_CACHEFLUSH_H
 #define _BLACKFIN_CACHEFLUSH_H
 
-extern void blackfin_icache_dcache_flush_range(unsigned int, unsigned int);
-extern void blackfin_icache_flush_range(unsigned int, unsigned int);
-extern void blackfin_dcache_flush_range(unsigned int, unsigned int);
-extern void blackfin_dcache_invalidate_range(unsigned int, unsigned int);
-extern void blackfin_dflush_page(void *);
+extern void blackfin_icache_dcache_flush_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_icache_flush_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_dflush_page(void *page);
 
 #define flush_dcache_mmap_lock(mapping)                do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)      do { } while (0)
@@ -85,4 +85,21 @@ do { memcpy(dst, src, len); \
 # define flush_dcache_page(page)                       do { } while (0)
 #endif
 
+extern unsigned long reserved_mem_dcache_on;
+extern unsigned long reserved_mem_icache_on;
+
+static inline int bfin_addr_dcachable(unsigned long addr)
+{
+#ifdef CONFIG_BFIN_DCACHE
+       if (addr < (_ramend - DMA_UNCACHED_REGION))
+               return 1;
+#endif
+
+       if (reserved_mem_dcache_on &&
+               addr >= _ramend && addr < physical_mem_end)
+               return 1;
+
+       return 0;
+}
+
 #endif                         /* _BLACKFIN_ICACHEFLUSH_H */
index d179b747ff034933b55b86172bd1bfdd6258f121..f845b41147ba209184182a79194383465cc20fb6 100644 (file)
@@ -87,23 +87,6 @@ extern u_long dpdt_swapcount_table[];
 
 #endif /* CONFIG_MPU */
 
-extern unsigned long reserved_mem_dcache_on;
-extern unsigned long reserved_mem_icache_on;
-
 extern void generate_cplb_tables(void);
 
-static inline int bfin_addr_dcachable(unsigned long addr)
-{
-#ifdef CONFIG_BFIN_DCACHE
-       if (addr < (_ramend - DMA_UNCACHED_REGION))
-               return 1;
-#endif
-
-       if (reserved_mem_dcache_on &&
-               addr >= _ramend && addr < physical_mem_end)
-               return 1;
-
-       return 0;
-}
-
 #endif
index 67a03a8a353e019a28a1c86918ee6367eb978d69..cdbfcfc30f6a693c170d6db57e80a3af04c5cf50 100644 (file)
@@ -122,6 +122,6 @@ do {                                                                                        \
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif
index cbbf7ffdbbff1d4450e29ef0b68c5d1cde99c168..7dc77a21fdf33aeb2f94fc42ad97db7c1f9447a0 100644 (file)
@@ -134,6 +134,36 @@ extern void dma_insb(unsigned long port, void *addr, unsigned short count);
 extern void dma_insw(unsigned long port, void *addr, unsigned short count);
 extern void dma_insl(unsigned long port, void *addr, unsigned short count);
 
+static inline void readsl(const void __iomem *addr, void *buf, int len)
+{
+       insl((unsigned long)addr, buf, len);
+}
+
+static inline void readsw(const void __iomem *addr, void *buf, int len)
+{
+       insw((unsigned long)addr, buf, len);
+}
+
+static inline void readsb(const void __iomem *addr, void *buf, int len)
+{
+       insb((unsigned long)addr, buf, len);
+}
+
+static inline void writesl(const void __iomem *addr, const void *buf, int len)
+{
+       outsl((unsigned long)addr, buf, len);
+}
+
+static inline void writesw(const void __iomem *addr, const void *buf, int len)
+{
+       outsw((unsigned long)addr, buf, len);
+}
+
+static inline void writesb(const void __iomem *addr, const void *buf, int len)
+{
+       outsb((unsigned long)addr, buf, len);
+}
+
 /*
  * Map some physical address range into the kernel address space.
  */
index 22b0806161bb614b2179c7ec1eee002a0255779e..248aeb06680527f49dd24d3e559295ac9fdf78ed 100644 (file)
@@ -16,7 +16,7 @@ typedef unsigned long long cycles_t;
 static inline cycles_t get_cycles(void)
 {
        unsigned long tmp, tmp2;
-       __asm__("%0 = cycles; %1 = cycles2;" : "=d"(tmp), "=d"(tmp2));
+       __asm__ __volatile__("%0 = cycles; %1 = cycles2;" : "=d"(tmp), "=d"(tmp2));
        return tmp | ((cycles_t)tmp2 << 32);
 }
 
index 5094677fd09eae3235b524490960b157e662ea5f..baa52e261f0d501dab0206a4edaebdc678f9b33f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 
 #include <asm/blackfin.h>
+#include <asm/cacheflush.h>
 #include <asm/cplbinit.h>
 #include <asm/mmu_context.h>
 
@@ -144,9 +145,7 @@ static noinline int dcplb_miss(void)
 
        d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
 #ifdef CONFIG_BFIN_DCACHE
-       if (addr < _ramend - DMA_UNCACHED_REGION ||
-           (reserved_mem_dcache_on && addr >= _ramend &&
-            addr < physical_mem_end)) {
+       if (bfin_addr_dcachable(addr)) {
                d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
 #ifdef CONFIG_BFIN_WT
                d_data |= CPLB_L1_AOW | CPLB_WT;
index 301252e84441cca9a345b8a5b05462c5c3c267b5..512f8c92ead511f2286a4a9f688763becd9ca8ed 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 
 #include <asm/blackfin.h>
+#include <asm/cacheflush.h>
 #include <asm/cplb.h>
 #include <asm/cplbinit.h>
 
index 6588170e3845be874e4c37b5e20b465f1c07fe39..0eb1da85db730e60c9a7e0e0373695650613268e 100644 (file)
@@ -88,7 +88,7 @@ ENTRY(_start_dma_code)
        r1 = r1 << 8;                    /* Shift it over                   */
        r0 = r1 | r0;                    /* add them all together           */
 #ifdef ANOMALY_05000265
-       r0 = BITSET(r0, 15);             /* Add 250 mV of hysteresis to SPORT input pins */
+       BITSET(r0, 15);                  /* Add 250 mV of hysteresis to SPORT input pins */
 #endif
 
        p0.h = hi(PLL_CTL);
index 619685b94d90cfea03dc7c9e5092295140e0f6eb..9fc95aaca439c26371577172026824e320fddd14 100644 (file)
@@ -79,7 +79,7 @@ ENTRY(_start_dma_code)
        r1 = r1 << 8;                    /* Shift it over                   */
        r0 = r1 | r0;                    /* add them all together           */
 #ifdef ANOMALY_05000265
-       r0 = BITSET(r0, 15);             /* Add 250 mV of hysteresis to SPORT input pins */
+       BITSET(r0, 15);                  /* Add 250 mV of hysteresis to SPORT input pins */
 #endif
 
        p0.h = hi(PLL_CTL);
index 34ab0e4e42423a29ff910f4f8fed6a8f07b4d5a6..f3d9e495230c04439357b1499874c918092a817e 100644 (file)
@@ -158,7 +158,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
        }
        if (uart->rts_pin >= 0) {
                gpio_request(uart->rts_pin, DRIVER_NAME);
-               gpio_direction_input(uart->rts_pin, 0);
+               gpio_direction_output(uart->rts_pin, 0);
        }
 #endif
 }
index dc5a30849c1515443471eb07fae9940c366a7b6f..8d394393201fd74d13ab5a13fbac6bf9d420bd57 100644 (file)
@@ -577,11 +577,6 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
 
 #if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)
 #include <linux/spi/ad7879.h>
-static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-
 static const struct ad7879_platform_data bfin_ad7879_ts_info = {
        .model                  = 7879, /* Model = AD7879 */
        .x_plate_ohms           = 620,  /* 620 Ohm from the touch datasheet */
@@ -597,6 +592,13 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
 };
 #endif
 
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
 static struct bfin5xx_spi_chip spidev_chip_info = {
        .enable_dma = 0,
@@ -750,7 +752,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .controller_data = &spi_ad7877_chip_info,
        },
 #endif
-#if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
        {
                .modalias = "ad7879",
                .platform_data = &bfin_ad7879_ts_info,
@@ -935,7 +937,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
        {
                I2C_BOARD_INFO("ad7142_joystick", 0x2C),
-               .irq = 55,
+               .irq = IRQ_PF5,
        },
 #endif
 #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
@@ -946,7 +948,14 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_keypad", 0x27),
-               .irq = 72,
+               .irq = IRQ_PG6,
+       },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+       {
+               I2C_BOARD_INFO("ad7879", 0x2F),
+               .irq = IRQ_PG5,
+               .platform_data = (void *)&bfin_ad7879_ts_info,
        },
 #endif
 };
index 559a7eef7a38e89080dac76391de783c5cb1cd28..f5c94bf80e3bbec8c61451a5e035bc868b66aec6 100644 (file)
@@ -88,7 +88,7 @@ ENTRY(_start_dma_code)
        r1 = r1 << 8;                    /* Shift it over                   */
        r0 = r1 | r0;                    /* add them all together           */
 #ifdef ANOMALY_05000265
-       r0 = BITSET(r0, 15);             /* Add 250 mV of hysteresis to SPORT input pins */
+       BITSET(r0, 15);                  /* Add 250 mV of hysteresis to SPORT input pins */
 #endif
 
        p0.h = hi(PLL_CTL);
index 051b05c88027130e2c05f190805ac31f9da29fa9..93b361dff27ba23bab6f471e154f2c69d1028eb3 100644 (file)
@@ -95,7 +95,7 @@ ENTRY(_start_dma_code)
        r1 = r1 << 8;                    /* Shift it over                   */
        r0 = r1 | r0;                    /* add them all together           */
 #ifdef ANOMALY_05000265
-       r0 = BITSET(r0, 15);             /* Add 250 mV of hysteresis to SPORT input pins */
+       BITSET(r0, 15);                  /* Add 250 mV of hysteresis to SPORT input pins */
 #endif
 
        p0.h = hi(PLL_CTL);
index 0b28137b3dea1958fc038a9f2b06f12d8a7a0c96..31a777a9e69996d51d0947de84c33883a23b8e1f 100644 (file)
@@ -78,7 +78,7 @@ ENTRY(_start_dma_code)
        r1 = r1 << 8;                    /* Shift it over                   */
        r0 = r1 | r0;                    /* add them all together           */
 #ifdef ANOMALY_05000265
-       r0 = BITSET(r0, 15);             /* Add 250 mV of hysteresis to SPORT input pins */
+       BITSET(r0, 15);                  /* Add 250 mV of hysteresis to SPORT input pins */
 #endif
 
        p0.h = hi(PLL_CTL);
index f5327264357cb2dd0a96d26eb4a734fc5bd3fddc..043bfcf26c52a2250c4399a484904e0e0906e9af 100644 (file)
@@ -158,7 +158,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
        }
        if (uart->rts_pin >= 0) {
                gpio_request(uart->rts_pin, DRIVER_NAME);
-               gpio_direction_input(uart->rts_pin, 0);
+               gpio_direction_output(uart->rts_pin, 0);
        }
 #endif
 }
index 85f8c79b3c377b1c2a9e0d4f01fc370a4e4bce6e..db532181fbdeb9200a6d445b6f7fd940cd088830 100644 (file)
 /*
- * File:         arch/blackfin/mach-common/cache.S
- * Based on:
- * Author:       LG Soft India
+ * Blackfin cache control code
  *
- * Created:
- * Description:  cache control support
+ * Copyright 2004-2008 Analog Devices Inc.
  *
- * Modified:
- *               Copyright 2004-2006 Analog Devices Inc.
+ * Enter bugs at http://blackfin.uclinux.org/
  *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/linkage.h>
-#include <asm/cplb.h>
-#include <asm/entry.h>
 #include <asm/blackfin.h>
 #include <asm/cache.h>
+#include <asm/page.h>
 
 .text
 
-/*
- * blackfin_cache_flush_range(start, end)
- * Invalidate all cache lines assocoiated with this
- * area of memory.
+/* Since all L1 caches work the same way, we use the same method for flushing
+ * them.  Only the actual flush instruction differs.  We write this in asm as
+ * GCC can be hard to coax into writing nice hardware loops.
  *
- * start:      Start address
- * end:                End address
+ * Also, we assume the following register setup:
+ * R0 = start address
+ * R1 = end address
  */
-ENTRY(_blackfin_icache_flush_range)
+.macro do_flush flushins:req optflushins optnopins label
+
+       /* end = ((end - 1) & -L1_CACHE_BYTES) + L1_CACHE_BYTES; */
+       R1 += -1;
        R2 = -L1_CACHE_BYTES;
-       R2 = R0 & R2;
-       P0 = R2;
-       P1 = R1;
-       CSYNC(R3);
-       IFLUSH [P0];
+       R1 = R1 & R2;
+       R1 += L1_CACHE_BYTES;
+
+       /* count = (end - start) >> L1_CACHE_SHIFT */
+       R2 = R1 - R0;
+       R2 >>= L1_CACHE_SHIFT;
+       P1 = R2;
+
+.ifnb \label
+\label :
+.endif
+       P0 = R0;
+       LSETUP (1f, 2f) LC1 = P1;
 1:
-       IFLUSH [P0++];
-       CC = P0 < P1 (iu);
-       IF CC JUMP 1b (bp);
-       IFLUSH [P0];
-       SSYNC(R3);
+.ifnb \optflushins
+       \optflushins [P0];
+.endif
+.ifb \optnopins
+2:
+.endif
+       \flushins [P0++];
+.ifnb \optnopins
+2: \optnopins;
+.endif
+
        RTS;
-ENDPROC(_blackfin_icache_flush_range)
+.endm
 
-/*
- * blackfin_icache_dcache_flush_range(start, end)
- * FLUSH all cache lines assocoiated with this
- * area of memory.
- *
- * start:      Start address
- * end:                End address
- */
+/* Invalidate all instruction cache lines assocoiated with this memory area */
+ENTRY(_blackfin_icache_flush_range)
+       do_flush IFLUSH, , nop
+ENDPROC(_blackfin_icache_flush_range)
 
+/* Flush all cache lines assocoiated with this area of memory. */
 ENTRY(_blackfin_icache_dcache_flush_range)
-       R2 = -L1_CACHE_BYTES;
-       R2 = R0 & R2;
-       P0 = R2;
-       P1 = R1;
-       CSYNC(R3);
-       IFLUSH [P0];
-1:
-       FLUSH [P0];
-       IFLUSH [P0++];
-       CC = P0 < P1 (iu);
-       IF CC JUMP 1b (bp);
-       IFLUSH [P0];
-       FLUSH [P0];
-       SSYNC(R3);
-       RTS;
+       do_flush IFLUSH, FLUSH
 ENDPROC(_blackfin_icache_dcache_flush_range)
 
 /* Throw away all D-cached data in specified region without any obligation to
- * write them back. However, we must clean the D-cached entries around the
- * boundaries of the start and/or end address is not cache aligned.
- *
- * Start: start address,
- * end  : end address.
+ * write them back.  Since the Blackfin ISA does not have an "invalidate"
+ * instruction, we use flush/invalidate.  Perhaps as a speed optimization we
+ * could bang on the DTEST MMRs ...
  */
-
 ENTRY(_blackfin_dcache_invalidate_range)
-       R2 = -L1_CACHE_BYTES;
-       R2 = R0 & R2;
-       P0 = R2;
-       P1 = R1;
-       CSYNC(R3);
-       FLUSHINV[P0];
-1:
-       FLUSHINV[P0++];
-       CC = P0 < P1 (iu);
-       IF CC JUMP 1b (bp);
-
-       /* If the data crosses a cache line, then we'll be pointing to
-        * the last cache line, but won't have flushed/invalidated it yet,
-        * so do one more.
-        */
-       FLUSHINV[P0];
-       SSYNC(R3);
-       RTS;
+       do_flush FLUSHINV
 ENDPROC(_blackfin_dcache_invalidate_range)
 
+/* Flush all data cache lines assocoiated with this memory area */
 ENTRY(_blackfin_dcache_flush_range)
-       R2 = -L1_CACHE_BYTES;
-       R2 = R0 & R2;
-       P0 = R2;
-       P1 = R1;
-       CSYNC(R3);
-       FLUSH[P0];
-1:
-       FLUSH[P0++];
-       CC = P0 < P1 (iu);
-       IF CC JUMP 1b (bp);
-
-       /* If the data crosses a cache line, then we'll be pointing to
-        * the last cache line, but won't have flushed it yet, so do
-        * one more.
-        */
-       FLUSH[P0];
-       SSYNC(R3);
-       RTS;
+       do_flush FLUSH, , , .Ldfr
 ENDPROC(_blackfin_dcache_flush_range)
 
+/* Our headers convert the page structure to an address, so just need to flush
+ * its contents like normal.  We know the start address is page aligned (which
+ * greater than our cache alignment), as is the end address.  So just jump into
+ * the middle of the dcache flush function.
+ */
 ENTRY(_blackfin_dflush_page)
        P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
-       P0 = R0;
-       CSYNC(R3);
-       FLUSH[P0];
-       LSETUP (.Lfl1, .Lfl1) LC0 = P1;
-.Lfl1: FLUSH [P0++];
-       SSYNC(R3);
-       RTS;
+       jump .Ldfr;
 ENDPROC(_blackfin_dflush_page)
index 75cdad291e889be2b3b1a761c6304d9308d46118..c22c47b601273771d71306bbfbb264a6c66b8605 100644 (file)
@@ -158,8 +158,6 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
                                                 dpm_state_table[index].tscale);
        }
 
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-
        policy->cpuinfo.transition_latency = (bfin_read_PLL_LOCKCNT() / (sclk / 1000000)) * 1000;
        /*Now ,only support one cpu */
        policy->cur = cclk;
index 3069df580729d06b18cf4a47b34ec79fe540ebca..f123a62e2451ca5acaabbd866030118267a93e35 100644 (file)
@@ -206,6 +206,60 @@ ENTRY(_real_start)
        w[p0] = r0;
        ssync;
 
+#if L1_DATA_A_LENGTH > 0
+       r1.l = __sbss_l1;
+       r1.h = __sbss_l1;
+       r2.l = __ebss_l1;
+       r2.h = __ebss_l1;
+       r0 = 0 (z);
+       r2 = r2 - r1;
+       cc = r2 == 0;
+       if cc jump .L_a_l1_done;
+       r2 >>= 2;
+       p1 = r1;
+       p2 = r2;
+       lsetup (.L_clear_a_l1, .L_clear_a_l1 ) lc0 = p2;
+.L_clear_a_l1:
+       [p1++] = r0;
+.L_a_l1_done:
+#endif
+
+#if L1_DATA_B_LENGTH > 0
+       r1.l = __sbss_b_l1;
+       r1.h = __sbss_b_l1;
+       r2.l = __ebss_b_l1;
+       r2.h = __ebss_b_l1;
+       r0 = 0 (z);
+       r2 = r2 - r1;
+       cc = r2 == 0;
+       if cc jump .L_b_l1_done;
+       r2 >>= 2;
+       p1 = r1;
+       p2 = r2;
+       lsetup (.L_clear_b_l1, .L_clear_b_l1 ) lc0 = p2;
+.L_clear_b_l1:
+       [p1++] = r0;
+.L_b_l1_done:
+#endif
+
+#if L2_LENGTH > 0
+       r1.l = __sbss_l2;
+       r1.h = __sbss_l2;
+       r2.l = __ebss_l2;
+       r2.h = __ebss_l2;
+       r0 = 0 (z);
+       r2 = r2 - r1;
+       cc = r2 == 0;
+       if cc jump .L_l2_done;
+       r2 >>= 2;
+       p1 = r1;
+       p2 = r2;
+       lsetup (.L_clear_l2, .L_clear_l2 ) lc0 = p2;
+.L_clear_l2:
+       [p1++] = r0;
+.L_l2_done:
+#endif
+
        /* Zero out the bss region
         * Note: this will fail if bss is 0 bytes ...
         */
index 8e5a3cab8ad7f3dcfd3e48a3b5e48c98deab61d0..ee391ecb5bc9bb6e67f216ba265304ba791f6b13 100644 (file)
@@ -85,7 +85,6 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
        int result;
 
        /* cpuinfo and default policy values */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        policy->cpuinfo.transition_latency = 1000000; /* 1ms */
        policy->cur = cris_freq_get_cpu_frequency(0);
 
index d57631c0d8d1c09bc35393cfa7b18019dd00116b..58bd71e5bda95415621819222665ba24a74e658e 100644 (file)
@@ -81,7 +81,6 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
        int result;
 
        /* cpuinfo and default policy values */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        policy->cpuinfo.transition_latency = 1000000;   /* 1ms */
        policy->cur = cris_freq_get_cpu_frequency(0);
 
index d1113c5031f5f4f19a16314378e63ab3a9889301..be722fc1acff523986182dcef23da7b15a3c2534 100644 (file)
@@ -211,7 +211,7 @@ static int cmode_procctl(ctl_table *ctl, int write, struct file *filp,
        return try_set_cmode(new_cmode)?:*lenp;
 }
 
-static int cmode_sysctl(ctl_table *table, int __user *name, int nlen,
+static int cmode_sysctl(ctl_table *table,
                        void __user *oldval, size_t __user *oldlenp,
                        void __user *newval, size_t newlen)
 {
@@ -314,7 +314,7 @@ static int p0_procctl(ctl_table *ctl, int write, struct file *filp,
        return try_set_p0(new_p0)?:*lenp;
 }
 
-static int p0_sysctl(ctl_table *table, int __user *name, int nlen,
+static int p0_sysctl(ctl_table *table,
                     void __user *oldval, size_t __user *oldlenp,
                     void __user *newval, size_t newlen)
 {
@@ -358,7 +358,7 @@ static int cm_procctl(ctl_table *ctl, int write, struct file *filp,
        return try_set_cm(new_cm)?:*lenp;
 }
 
-static int cm_sysctl(ctl_table *table, int __user *name, int nlen,
+static int cm_sysctl(ctl_table *table,
                     void __user *oldval, size_t __user *oldlenp,
                     void __user *newval, size_t newlen)
 {
index 64ee58d748be807131c2188d659ec1dc0bceba8a..52ff9aec799d29c84a649aa128ccb985b60cd68c 100644 (file)
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(dma_free_coherent);
  * The 32-bit bus address to use is returned.
  *
  * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
+ * until either dma_unmap_single or pci_dma_sync_single is performed.
  */
 dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
                          enum dma_data_direction direction)
@@ -129,7 +129,7 @@ EXPORT_SYMBOL(dma_map_single);
 /*
  * Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
+ * above dma_map_single interface.  Here the scatter gather list
  * elements are each tagged with the appropriate dma address
  * and length.  They are obtained via sg_dma_{address,length}(SG).
  *
@@ -139,7 +139,7 @@ EXPORT_SYMBOL(dma_map_single);
  *       The routine returns the number of addr/length pairs actually
  *       used, at most nents.
  *
- * Device ownership issues as mentioned above for pci_map_single are
+ * Device ownership issues as mentioned above for dma_map_single are
  * the same here.
  */
 int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
@@ -158,3 +158,20 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 }
 
 EXPORT_SYMBOL(dma_map_sg);
+
+/*
+ * Map a single page of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Device ownership issues as mentioned above for dma_map_single are
+ * the same here.
+ */
+dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+                       size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+       flush_dcache_page(page);
+       return (dma_addr_t) page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
index 662f7b12d005fa532b834ec06838cf5ae56bc264..3ddedebc4eb3db1a1bbc25a7a10dd2e1fd1e66e5 100644 (file)
@@ -61,7 +61,7 @@ EXPORT_SYMBOL(dma_map_single);
 /*
  * Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
+ * above dma_map_single interface.  Here the scatter gather list
  * elements are each tagged with the appropriate dma address
  * and length.  They are obtained via sg_dma_{address,length}(SG).
  *
@@ -71,7 +71,7 @@ EXPORT_SYMBOL(dma_map_single);
  *       The routine returns the number of addr/length pairs actually
  *       used, at most nents.
  *
- * Device ownership issues as mentioned above for pci_map_single are
+ * Device ownership issues as mentioned above for dma_map_single are
  * the same here.
  */
 int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
@@ -105,6 +105,13 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 
 EXPORT_SYMBOL(dma_map_sg);
 
+/*
+ * Map a single page of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Device ownership issues as mentioned above for dma_map_single are
+ * the same here.
+ */
 dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
                        size_t size, enum dma_data_direction direction)
 {
index edae117fcc2bcc93ef81a8d1d8a167e6a2050a68..43d67534c7122f44e5787ccb36a3faed12489412 100644 (file)
@@ -201,38 +201,6 @@ void __init pcibios_resource_survey(void)
        pcibios_assign_resources();
 }
 
-int pcibios_enable_resources(struct pci_dev *dev, int mask)
-{
-       u16 cmd, old_cmd;
-       int idx;
-       struct resource *r;
-
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       old_cmd = cmd;
-       for(idx=0; idx<6; idx++) {
-               /* Only set up the requested stuff */
-               if (!(mask & (1<<idx)))
-                       continue;
-
-               r = &dev->resource[idx];
-               if (!r->start && r->end) {
-                       printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
-                       return -EINVAL;
-               }
-               if (r->flags & IORESOURCE_IO)
-                       cmd |= PCI_COMMAND_IO;
-               if (r->flags & IORESOURCE_MEM)
-                       cmd |= PCI_COMMAND_MEMORY;
-       }
-       if (dev->resource[PCI_ROM_RESOURCE].start)
-               cmd |= PCI_COMMAND_MEMORY;
-       if (cmd != old_cmd) {
-               printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
-       }
-       return 0;
-}
-
 /*
  *  If we set up a device for bus mastering, we need to check the latency
  *  timer as certain crappy BIOSes forget to set it properly.
index 0c7bf39dc7298cb781c0b2b7ecf6c2a1be451b0c..f3fe5591479388ba6c2b3d7b6320740dfd392701 100644 (file)
@@ -29,7 +29,6 @@ extern unsigned int __nongpreldata pci_probe;
 extern unsigned int pcibios_max_latency;
 
 void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *, int);
 
 /* pci-vdk.c */
 
index f003cfa68b7a0cbe78ee1ca3444dd6deb7884e18..0f41c3a72da5f5cf042052554a3add718c238946 100644 (file)
@@ -412,7 +412,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
        int err;
 
-       if ((err = pcibios_enable_resources(dev, mask)) < 0)
+       if ((err = pci_enable_resources(dev, mask)) < 0)
                return err;
        if (!dev->msi_enabled)
                pcibios_enable_irq(dev);
index 1b851db341865420257f388a9fc9e31828a1d0e8..0708284f85fb3d690d4e649366ea056282a171b8 100644 (file)
@@ -87,8 +87,6 @@ void __init paging_init(void)
 
                pkmap_page_table = alloc_bootmem_pages(PAGE_SIZE);
 
-               memset(pkmap_page_table, 0, PAGE_SIZE);
-
                pge = swapper_pg_dir + pgd_index_k(PKMAP_BASE);
                pue = pud_offset(pge, PKMAP_BASE);
                pme = pmd_offset(pue, PKMAP_BASE);
index 107cb5bb9f39f0b99a3ba2a0841d0a373a19dfbf..c7966746fbfec582938b77a37baaed384d1b0ec2 100644 (file)
@@ -62,6 +62,10 @@ config GENERIC_TIME
        bool
        default y
 
+config GENERIC_BUG
+        bool
+        depends on BUG
+
 config TIME_LOW_RES
        bool
        default y
index 582797db9603f1fa19b3a0d2fae692bf1510efb2..b65dcfe51d9ca2ae26b890de5f1f070620b8b033 100644 (file)
@@ -1,5 +1,7 @@
 menu "Processor type and features"
 
+source "kernel/time/Kconfig"
+
 choice
        prompt "H8/300 platform"
        default H8300H_GENERIC
@@ -11,6 +13,7 @@ config H8300H_GENERIC
 
 config H8300H_AKI3068NET
        bool "AE-3068/69"
+       select CONFIG_H83068
        help
          AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
          More Information. (Japanese Only)
@@ -21,6 +24,7 @@ config H8300H_AKI3068NET
 
 config H8300H_H8MAX
        bool "H8MAX"
+       select CONFIG_H83068
        help
          H8MAX Evaluation Board Support
          More Information. (Japanese Only)
@@ -28,6 +32,7 @@ config H8300H_H8MAX
 
 config H8300H_SIM
        bool "H8/300H Simulator"
+       select CONFIG_H83007
        help
          GDB Simulator Support
          More Information.
@@ -40,6 +45,7 @@ config H8S_GENERIC
 
 config H8S_EDOSK2674
        bool "EDOSK-2674"
+       select CONFIG_H8S2768
        help
          Renesas EDOSK-2674 Evaluation Board Support
          More Information.
@@ -55,44 +61,37 @@ config H8S_SIM
 
 endchoice
 
-if (H8300H_GENERIC || H8S_GENERIC)
-menu "Detail Selection"
-if (H8300H_GENERIC)
 choice
        prompt "CPU Selection"
 
 config H83002
        bool "H8/3001,3002,3003"
+       select CPU_H8300H
 
 config H83007
        bool "H8/3006,3007"
+       select CPU_H8300H
 
 config H83048
        bool "H8/3044,3045,3046,3047,3048,3052"
+       select CPU_H8300H
 
 config H83068
        bool "H8/3065,3066,3067,3068,3069"
-endchoice
-endif
-
-if (H8S_GENERIC)
-choice
-       prompt "CPU Selection"
+       select CPU_H8300H
 
 config H8S2678
        bool "H8S/2670,2673,2674R,2675,2676"
+       select CPU_H8S
+
 endchoice
-endif
 
 config CPU_CLOCK
        int "CPU Clock Frequency (/1KHz)"
        default "20000"
        help
          CPU Clock Frequency divide to 1000
-endmenu
-endif
 
-if (H8300H_GENERIC || H8S_GENERIC || H8300H_SIM || H8S_SIM || H8S_EDOSK2674)
 choice
        prompt "Kernel executes from"
        ---help---
@@ -107,75 +106,61 @@ config ROMKERNEL
        bool "ROM"
        help
          The kernel will be resident in FLASH/ROM when running.
-
 endchoice
-endif
 
-if (H8300H_AKI3068NET)
-config H83068
-       bool
-       default y
 
-config CPU_CLOCK
-       int
-       default "20000"
-
-config RAMKERNEL
+config CPU_H8300H
        bool
+       depends on (H83002 || H83007 || H83048 || H83068)
        default y
-endif
 
-if (H8300H_H8MAX)
-config H83068
+config CPU_H8S
        bool
+       depends on H8S2678
        default y
 
-config CPU_CLOCK
-       int
-       default 25000
+choice
+       prompt "Timer"
+config H8300_TIMER8
+       bool "8bit timer (2ch cascade)"
+       depends on (H83007 || H83068 || H8S2678)
 
-config RAMKERNEL
-       bool
-       default y
-endif
+config H8300_TIMER16
+       bool "16bit timer"
+       depends on (H83007 || H83068)
 
-if (H8300H_SIM)
-config H83007
-       bool
-       default y
+config H8300_ITU
+       bool "ITU"
+       depends on (H83002 || H83048)
 
-config CPU_CLOCK
-       int
-       default "16000"
-endif
+config H8300_TPU
+       bool "TPU"
+       depends on H8S2678
+endchoice
 
-if (H8S_EDOSK2674)
-config H8S2678
-       bool
-       default y
-config CPU_CLOCK
-       int
-       default 33000
+if H8300_TIMER8
+choice
+       prompt "Timer Channel"
+config H8300_TIMER8_CH0
+       bool "Channel 0"
+config H8300_TIMER8_CH2
+       bool "Channel 2"
+       depends on CPU_H8300H
+endchoice
 endif
 
-if (H8S_SIM)
-config H8S2678
-       bool
-       default y
-config CPU_CLOCK
-       int
-       default 33000
-endif
+config H8300_TIMER16_CH
+       int "16bit timer channel (0 - 2)"
+       depends on H8300_TIMER16
+       range 0 2
 
-config CPU_H8300H
-       bool
-       depends on (H83002 || H83007 || H83048 || H83068)
-       default y
+config H8300_ITU_CH
+       int "ITU channel"
+       depends on H8300_ITU
 
-config CPU_H8S
-       bool
-       depends on H8S2678
-       default y
+config H8300_TPU_CH
+       int "TPU channel"
+       depends on H8300_TPU
 
 config PREEMPT
        bool "Preemptible Kernel"
index edddf5b086e5f447fa2117103015e6714d8a3786..887c19773185d2da7442fb81b5090a0742de571b 100644 (file)
@@ -1,4 +1,8 @@
 #ifndef _H8300_BUG_H
 #define _H8300_BUG_H
+
+/* always true */
+#define is_valid_bugaddr(addr) (1)
+
 #include <asm-generic/bug.h>
 #endif
index a8b57d1f41286261434957bc408057b487628408..94e2284c88168fba8a42afc0008aa8cb1c53944e 100644 (file)
@@ -55,7 +55,7 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #define R_H8_NONE       0
 #define R_H8_DIR32      1
index 26dc6ccd9441a2237ada1f7168131f07402949a9..33e842f3284bf7cdec4b0a3aec59835cbe0b20b0 100644 (file)
@@ -295,6 +295,40 @@ static __inline__ void ctrl_outl(unsigned long b, unsigned long addr)
         *(volatile unsigned long*)addr = b;
 }
 
+static __inline__ void ctrl_bclr(int b, unsigned long addr)
+{
+       if (__builtin_constant_p(b))
+               switch (b) {
+               case 0: __asm__("bclr #0,@%0"::"r"(addr)); break;
+               case 1: __asm__("bclr #1,@%0"::"r"(addr)); break;
+               case 2: __asm__("bclr #2,@%0"::"r"(addr)); break;
+               case 3: __asm__("bclr #3,@%0"::"r"(addr)); break;
+               case 4: __asm__("bclr #4,@%0"::"r"(addr)); break;
+               case 5: __asm__("bclr #5,@%0"::"r"(addr)); break;
+               case 6: __asm__("bclr #6,@%0"::"r"(addr)); break;
+               case 7: __asm__("bclr #7,@%0"::"r"(addr)); break;
+               }
+       else
+               __asm__("bclr %w0,@%1"::"r"(b), "r"(addr));
+}
+
+static __inline__ void ctrl_bset(int b, unsigned long addr)
+{
+       if (__builtin_constant_p(b))
+               switch (b) {
+               case 0: __asm__("bset #0,@%0"::"r"(addr)); break;
+               case 1: __asm__("bset #1,@%0"::"r"(addr)); break;
+               case 2: __asm__("bset #2,@%0"::"r"(addr)); break;
+               case 3: __asm__("bset #3,@%0"::"r"(addr)); break;
+               case 4: __asm__("bset #4,@%0"::"r"(addr)); break;
+               case 5: __asm__("bset #5,@%0"::"r"(addr)); break;
+               case 6: __asm__("bset #6,@%0"::"r"(addr)); break;
+               case 7: __asm__("bset #7,@%0"::"r"(addr)); break;
+               }
+       else
+               __asm__("bset %w0,@%1"::"r"(b), "r"(addr));
+}
+
 /* Pages to physical address... */
 #define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
 #define page_to_bus(page)       ((page - mem_map) << PAGE_SHIFT)
index 1a47dc6691fb34b7532266b94ee9fe3faee0a199..1b7300e0a175b3214ca0368217afb88a50a37c53 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: md.h,v 1.1 2002/11/19 02:09:26 gerg Exp $
+/*
  * md.h: High speed xor_block operation for RAID4/5 
  *
  */
index 4b8e475908ae0c9eab94c5ac55cb7e2c36216000..d98d97685f068da986c8639bd29953d94a8ceb8d 100644 (file)
@@ -155,4 +155,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
 
 #define arch_align_stack(x) (x)
 
+void die(char *str, struct pt_regs *fp, unsigned long err);
+
 #endif /* _H8300_SYSTEM_H */
index 6c248c3c5c3b92cf9084da1b3542440b4b920b49..8d4d2a54be9efd83afc94935b359a59288504911 100644 (file)
@@ -7,6 +7,6 @@ extra-y := vmlinux.lds
 obj-y := process.o traps.o ptrace.o irq.o \
         sys_h8300.o time.o signal.o \
          setup.o gpio.o init_task.o syscalls.o \
-        entry.o
+        entry.o timer/
 
 obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o 
index 4fd7138a6e03d01217d92517d83fb58f531cd9d1..cfc9127d2cede26312fcaef364a35d6be0c95080 100644 (file)
@@ -114,9 +114,10 @@ int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
                    struct module *me)
 {
-       return 0;
+       return module_bug_finalize(hdr, sechdrs, me);
 }
 
 void module_arch_cleanup(struct module *mod)
 {
+       module_bug_cleanup(mod);
 }
index e37c835e67cf2bee6538e07a50913d08cb7a6eca..7f2d6cfbb4b6091b2f6c7523ca004582b766349e 100644 (file)
 #include <linux/profile.h>
 
 #include <asm/io.h>
-#include <asm/target_time.h>
+#include <asm/timer.h>
 
 #define        TICK_SIZE (tick_nsec / 1000)
 
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+void h8300_timer_tick(void)
 {
-       /* may need to kick the hardware timer */
-       platform_timer_eoi();
-
+       if (current->pid)
+               profile_tick(CPU_PROFILING);
+       write_seqlock(&xtime_lock);
        do_timer(1);
-#ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
-#endif
-       profile_tick(CPU_PROFILING);
+       write_sequnlock(&xtime_lock);
+       update_process_times(user_mode(get_irq_regs()));
 }
 
-void time_init(void)
+void __init time_init(void)
 {
        unsigned int year, mon, day, hour, min, sec;
 
@@ -57,12 +51,13 @@ void time_init(void)
        year = 1980;
        mon = day = 1;
        hour = min = sec = 0;
-       platform_gettod (&year, &mon, &day, &hour, &min, &sec);
-
+#ifdef CONFIG_H8300_GETTOD
+       h8300_gettod (&year, &mon, &day, &hour, &min, &sec);
+#endif
        if ((year += 1900) < 1970)
                year += 100;
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
        xtime.tv_nsec = 0;
 
-       platform_timer_setup(timer_interrupt);
+       h8300_timer_setup();
 }
diff --git a/arch/h8300/kernel/timer/Makefile b/arch/h8300/kernel/timer/Makefile
new file mode 100644 (file)
index 0000000..bef0510
--- /dev/null
@@ -0,0 +1,6 @@
+# h8300 internal timer handler
+
+obj-$(CONFIG_H8300_TIMER8)  := timer8.o
+obj-$(CONFIG_H8300_TIMER16) := timer16.o
+obj-$(CONFIG_H8300_ITU)     := itu.o
+obj-$(CONFIG_H8300_TPU)     := tpu.o
diff --git a/arch/h8300/kernel/timer/itu.c b/arch/h8300/kernel/timer/itu.c
new file mode 100644 (file)
index 0000000..d1c9265
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  linux/arch/h8300/kernel/timer/itu.c
+ *
+ *  Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ *  ITU Timer Handler
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs306x.h>
+
+#if CONFIG_H8300_ITU_CH == 0
+#define ITUBASE        0xffff64
+#define ITUIRQ 24
+#elif CONFIG_H8300_ITU_CH == 1
+#define ITUBASE        0xffff6e
+#define ITUIRQ 28
+#elif CONFIG_H8300_ITU_CH == 2
+#define ITUBASE        0xffff78
+#define ITUIRQ 32
+#elif CONFIG_H8300_ITU_CH == 3
+#define ITUBASE        0xffff82
+#define ITUIRQ 36
+#elif CONFIG_H8300_ITU_CH == 4
+#define ITUBASE        0xffff92
+#define ITUIRQ 40
+#else
+#error Unknown timer channel.
+#endif
+
+#define TCR    0
+#define TIOR   1
+#define TIER   2
+#define TSR    3
+#define TCNT   4
+#define GRA    6
+#define GRB    8
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+       h8300_timer_tick();
+       ctrl_bclr(IMFA, ITUBASE + TSR);
+       return IRQ_HANDLED;
+}
+
+static struct irqaction itu_irq = {
+       .name           = "itu",
+       .handler        = timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .mask           = CPU_MASK_NONE,
+};
+
+static const int __initdata divide_rate[] = {1, 2, 4, 8};
+
+void __init h8300_timer_setup(void)
+{
+       unsigned int div;
+       unsigned int cnt;
+
+       calc_param(cnt, div, divide_rate, 0x10000);
+
+       setup_irq(ITUIRQ, &itu_irq);
+
+       /* initalize timer */
+       ctrl_outb(0, TSTR);
+       ctrl_outb(CCLR0 | div, ITUBASE + TCR);
+       ctrl_outb(0x01, ITUBASE + TIER);
+       ctrl_outw(cnt, ITUBASE + GRA);
+       ctrl_bset(CONFIG_H8300_ITU_CH, TSTR);
+}
diff --git a/arch/h8300/kernel/timer/timer16.c b/arch/h8300/kernel/timer/timer16.c
new file mode 100644 (file)
index 0000000..e14271b
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *  linux/arch/h8300/kernel/timer/timer16.c
+ *
+ *  Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ *  16bit Timer Handler
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs306x.h>
+
+/* 16bit timer */
+#if CONFIG_H8300_TIMER16_CH == 0
+#define _16BASE        0xffff78
+#define _16IRQ 24
+#elif CONFIG_H8300_TIMER16_CH == 1
+#define _16BASE        0xffff80
+#define _16IRQ 28
+#elif CONFIG_H8300_TIMER16_CH == 2
+#define _16BASE        0xffff88
+#define _16IRQ 32
+#else
+#error Unknown timer channel.
+#endif
+
+#define TCR    0
+#define TIOR   1
+#define TCNT   2
+#define GRA    4
+#define GRB    6
+
+#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*10000 /* Timer input freq. */
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+       h8300_timer_tick();
+       ctrl_bclr(CONFIG_H8300_TIMER16_CH, TISRA);
+       return IRQ_HANDLED;
+}
+
+static struct irqaction timer16_irq = {
+       .name           = "timer-16",
+       .handler        = timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .mask           = CPU_MASK_NONE,
+};
+
+static const int __initdata divide_rate[] = {1, 2, 4, 8};
+
+void __init h8300_timer_setup(void)
+{
+       unsigned int div;
+       unsigned int cnt;
+
+       calc_param(cnt, div, divide_rate, 0x10000);
+
+       setup_irq(_16IRQ, &timer16_irq);
+
+       /* initalize timer */
+       ctrl_outb(0, TSTR);
+       ctrl_outb(CCLR0 | div, _16BASE + TCR);
+       ctrl_outw(cnt, _16BASE + GRA);
+       ctrl_bset(4 + CONFIG_H8300_TIMER16_CH, TISRA);
+       ctrl_bset(CONFIG_H8300_TIMER16_CH, TSTR);
+}
diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c
new file mode 100644 (file)
index 0000000..0556d7c
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  linux/arch/h8300/kernel/cpu/timer/timer8.c
+ *
+ *  Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ *  8bit Timer Handler
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/profile.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/timer.h>
+#if defined(CONFIG_CPU_H8300H)
+#include <asm/regs306x.h>
+#endif
+#if defined(CONFIG_CPU_H8S)
+#include <asm/regs267x.h>
+#endif
+
+/* 8bit timer x2 */
+#define CMFA   6
+
+#if defined(CONFIG_H8300_TIMER8_CH0)
+#define _8BASE _8TCR0
+#ifdef CONFIG_CPU_H8300H
+#define _8IRQ  36
+#endif
+#ifdef CONFIG_CPU_H8S
+#define _8IRQ  72
+#endif
+#elif defined(CONFIG_H8300_TIMER8_CH2)
+#ifdef CONFIG_CPU_H8300H
+#define _8BASE _8TCR2
+#define _8IRQ  40
+#endif
+#endif
+
+#ifndef _8BASE
+#error Unknown timer channel.
+#endif
+
+#define _8TCR  0
+#define _8TCSR 2
+#define TCORA  4
+#define TCORB  6
+#define _8TCNT 8
+
+#define CMIEA  0x40
+#define CCLR_CMA 0x08
+#define CKS2   0x04
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+       h8300_timer_tick();
+       ctrl_bclr(CMFA, _8BASE + _8TCSR);
+       return IRQ_HANDLED;
+}
+
+static struct irqaction timer8_irq = {
+       .name           = "timer-8",
+       .handler        = timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .mask           = CPU_MASK_NONE,
+};
+
+static const int __initdata divide_rate[] = {8, 64, 8192};
+
+void __init h8300_timer_setup(void)
+{
+       unsigned int div;
+       unsigned int cnt;
+
+       calc_param(cnt, div, divide_rate, 0x10000);
+       div++;
+
+       setup_irq(_8IRQ, &timer8_irq);
+
+#if defined(CONFIG_CPU_H8S)
+       /* Timer module enable */
+       ctrl_bclr(0, MSTPCRL)
+#endif
+
+       /* initalize timer */
+       ctrl_outw(cnt, _8BASE + TCORA);
+       ctrl_outw(0x0000, _8BASE + _8TCSR);
+       ctrl_outw((CMIEA|CCLR_CMA|CKS2) << 8 | div,
+                 _8BASE + _8TCR);
+}
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c
new file mode 100644 (file)
index 0000000..df7f453
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *  linux/arch/h8300/kernel/timer/tpu.c
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  TPU Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs267x.h>
+
+/* TPU */
+#if CONFIG_H8300_TPU_CH == 0
+#define TPUBASE        0xffffd0
+#define TPUIRQ 40
+#elif CONFIG_H8300_TPU_CH == 1
+#define TPUBASE        0xffffe0
+#define TPUIRQ 48
+#elif CONFIG_H8300_TPU_CH == 2
+#define TPUBASE        0xfffff0
+#define TPUIRQ 52
+#elif CONFIG_H8300_TPU_CH == 3
+#define TPUBASE        0xfffe80
+#define TPUIRQ 56
+#elif CONFIG_H8300_TPU_CH == 4
+#define TPUBASE        0xfffe90
+#define TPUIRQ 64
+#else
+#error Unknown timer channel.
+#endif
+
+#define _TCR   0
+#define _TMDR  1
+#define _TIOR  2
+#define _TIER  4
+#define _TSR   5
+#define _TCNT  6
+#define _GRA   8
+#define _GRB   10
+
+#define CCLR0  0x20
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+       h8300_timer_tick();
+       ctrl_bclr(0, TPUBASE + _TSR);
+       return IRQ_HANDLED;
+}
+
+static struct irqaction tpu_irq = {
+       .name           = "tpu",
+       .handler        = timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .mask           = CPU_MASK_NONE,
+};
+
+const static int __initdata divide_rate[] = {
+#if CONFIG_H8300_TPU_CH == 0
+       1,4,16,64,0,0,0,0,
+#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5)
+       1,4,16,64,0,0,256,0,
+#elif (CONFIG_H8300_TPU_CH == 2) || (CONFIG_H8300_TPU_CH == 4)
+       1,4,16,64,0,0,0,1024,
+#elif CONFIG_H8300_TPU_CH == 3
+       1,4,16,64,0,1024,256,4096,
+#endif
+};
+
+void __init h8300_timer_setup(void)
+{
+       unsigned int cnt;
+       unsigned int div;
+
+       calc_param(cnt, div, divide_rate, 0x10000);
+
+       setup_irq(TPUIRQ, &tpu_irq);
+
+       /* TPU module enabled */
+       ctrl_bclr(3, MSTPCRH);
+
+       ctrl_outb(0, TSTR);
+       ctrl_outb(CCLR0 | div, TPUBASE + _TCR);
+       ctrl_outb(0, TPUBASE + _TMDR);
+       ctrl_outw(0, TPUBASE + _TIOR);
+       ctrl_outb(0x01, TPUBASE + _TIER);
+       ctrl_outw(cnt, TPUBASE + _GRA);
+       ctrl_bset(CONFIG_H8300_TPU_CH, TSTR);
+}
index f8f7d7ea97f17298522e599d22ce4e388cc5009a..3c0b66bc669eca40ced007cccb5d2ce5d6695904 100644 (file)
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/bug.h>
 
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
 #include <asm/page.h>
-#include <asm/gpio.h>
+
+static DEFINE_SPINLOCK(die_lock);
 
 /*
  * this must be called very early as the kernel might
@@ -94,16 +96,19 @@ static void dump(struct pt_regs *fp)
        printk("\n\n");
 }
 
-void die_if_kernel (char *str, struct pt_regs *fp, int nr)
+void die(char *str, struct pt_regs *fp, unsigned long err)
 {
-       extern int console_loglevel;
+       static int diecount;
 
-       if (!(fp->ccr & PS_S))
-               return;
+       oops_enter();
 
-       console_loglevel = 15;
+       console_verbose();
+       spin_lock_irq(&die_lock);
+       report_bug(fp->pc, fp);
+       printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++diecount);
        dump(fp);
 
+       spin_unlock_irq(&die_lock);
        do_exit(SIGSEGV);
 }
 
index 29e9af9f0e6a71942178bb9daff5f997e733060a..1d092abebf03bcfbeabfbe41f67b99cb1260e58e 100644 (file)
@@ -20,8 +20,6 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 
-extern void die_if_kernel(char *, struct pt_regs *, long);
-
 /*
  * This routine handles page faults.  It determines the problem, and
  * then passes it off to one of the appropriate routines.
@@ -50,7 +48,8 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
        } else
                printk(KERN_ALERT "Unable to handle kernel access");
        printk(" at virtual address %08lx\n",address);
-       die_if_kernel("Oops", regs, error_code);
+       if (!user_mode(regs))
+               die("Oops", regs, error_code);
        do_exit(SIGKILL);
 
        return 1;
index b03c328f8c703ac578faf82eb7a3a2fb929a5a18..b7ff78050b7f7237d9b9566b0d1eba4f4fac44eb 100644 (file)
@@ -3,4 +3,3 @@
 #
 
 extra-y := crt0_ram.o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8300h/aki3068net/timer.c b/arch/h8300/platform/h8300h/aki3068net/timer.c
deleted file mode 100644 (file)
index 27cd85d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  linux/arch/h8300/platform/h8300h/aki3068net/timer.c
- *
- *  Yoshinori Sato <ysato@users.sourcefoge.jp>
- *
- *  Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs306x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
-       /* setup 8bit timer ch2 */
-       ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2);      /* set interval */
-       ctrl_outb(0x00, _8TCSR2);                      /* no output */
-       request_irq(40, timer_int, 0, "timer", 0);
-       ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
-       *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
-                int *min, int *sec)
-{
-       *year = *mon = *day = *hour = *min = *sec = 0;
-}
index 32b964a9010e25a43720e5d39d3942a868e4ae42..2b12a170209e0086693aa2dcf71a3397857c21af 100644 (file)
@@ -3,4 +3,3 @@
 #
 
 extra-y :=  crt0_$(MODEL).o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8300h/generic/timer.c b/arch/h8300/platform/h8300h/generic/timer.c
deleted file mode 100644 (file)
index 6f5cefe..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  linux/arch/h8300/platform/h8300h/generic/timer.c
- *
- *  Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- *  Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <linux/timex.h>
-
-#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
-#include <asm/regs306x.h>
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
-       /* setup 8bit timer ch2 */
-       ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2);      /* set interval */
-       ctrl_outb(0x00, _8TCSR2);                      /* no output */
-       request_irq(40, timer_int, 0, "timer", 0);
-       ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
-       *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
-}
-#endif
-
-#if defined(CONFIG_H83002) || defined(CONFIG_H83048)
-/* FIXME! */
-#define TSTR 0x00ffff60
-#define TSNC 0x00ffff61
-#define TMDR 0x00ffff62
-#define TFCR 0x00ffff63
-#define TOER 0x00ffff90
-#define TOCR 0x00ffff91
-/* ITU0 */
-#define TCR  0x00ffff64
-#define TIOR 0x00ffff65
-#define TIER 0x00ffff66
-#define TSR  0x00ffff67
-#define TCNT 0x00ffff68
-#define GRA  0x00ffff6a
-#define GRB  0x00ffff6c
-
-#define CCLR_CMGRA 0x20
-#define CLK_DIV8 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
-       *(unsigned short *)GRA= H8300_TIMER_FREQ / HZ;  /* set interval */
-       *(unsigned short *)TCNT=0;                      /* clear counter */
-       ctrl_outb(0x80|CCLR_CMGRA|CLK_DIV8, TCR);       /* set ITU0 clock */
-       ctrl_outb(0x88, TIOR);                          /* no output */
-       request_irq(26, timer_int, 0, "timer", 0);
-       ctrl_outb(0xf9, TIER);                          /* compare match GRA interrupt */
-       ctrl_outb(ctrl_inb(TSNC) & ~0x01, TSNC);        /* ITU0 async */
-       ctrl_outb(ctrl_inb(TMDR) & ~0x01, TMDR);        /* ITU0 normal mode */
-       ctrl_outb(ctrl_inb(TSTR) | 0x01, TSTR);         /* ITU0 Start */
-       return 0;
-}
-
-void platform_timer_eoi(void)
-{
-       ctrl_outb(ctrl_inb(TSR) & ~0x01,TSR);
-}
-#endif
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
-                int *min, int *sec)
-{
-       *year = *mon = *day = *hour = *min = *sec = 0;
-}
index b03c328f8c703ac578faf82eb7a3a2fb929a5a18..b7ff78050b7f7237d9b9566b0d1eba4f4fac44eb 100644 (file)
@@ -3,4 +3,3 @@
 #
 
 extra-y := crt0_ram.o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8300h/h8max/timer.c b/arch/h8300/platform/h8300h/h8max/timer.c
deleted file mode 100644 (file)
index 85a574a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  linux/arch/h8300/platform/h8300h/h8max/timer.c
- *
- *  Yoshinori Sato <ysato@users.sourcefoge.jp>
- *
- *  Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs306x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
-       /* setup 8bit timer ch2 */
-       ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2);      /* set interval */
-       ctrl_outb(0x00, _8TCSR2);                      /* no output */
-       request_irq(40, timer_int, 0, "timer", 0);
-       ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
-       *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
-                int *min, int *sec)
-{
-       *year = *mon = *day = *hour = *min = *sec = 0;
-}
-
index f763654ac6fefc177b92bb6211dae9d2a6b34677..8e349723bb4f618b283da45e1e5797838ca7e0ea 100644 (file)
@@ -3,4 +3,3 @@
 #
 
 extra-y := crt0_$(MODEL).o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8s/edosk2674/timer.c b/arch/h8300/platform/h8s/edosk2674/timer.c
deleted file mode 100644 (file)
index bfb1424..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  linux/arch/h8300/platform/h8s/edosk2674/timer.c
- *
- *  Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- *  Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs267x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
-       /* 8bit timer module enabled */
-       ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL);
-       /* setup 8bit timer ch1 */
-       ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1);      /* set interval */
-       ctrl_outb(0x00, _8TCSR1);                        /* no output */
-       request_irq(76, timer_int, 0, "timer" ,0);
-       ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1);   /* start count */
-}
-
-void platform_timer_eoi(void)
-{
-       *(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
-                int *min, int *sec)
-{
-/* FIXME! not RTC support */
-       *year = *mon = *day = *hour = *min = *sec = 0;
-}
index 055d53a9811ba70dc41eb48050ee686486dbd0ae..44b4685c664c8bf7b52e7bfb6fd54d8655a165f3 100644 (file)
@@ -3,4 +3,3 @@
 #
 
 extra-y =  crt0_$(MODEL).o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8s/generic/timer.c b/arch/h8300/platform/h8s/generic/timer.c
deleted file mode 100644 (file)
index c2211c6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  linux/arch/h8300/platform/h8s/generic/timer.c
- *
- *  Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- *  Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs267x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
-       /* 8bit timer module enabled */
-       ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL);
-       /* setup 8bit timer ch1 */
-       ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1);      /* set interval */
-       ctrl_outb(0x00, _8TCSR1);                        /* no output */
-       request_irq(76, timer_int, 0, "timer" ,0);
-       ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1);   /* start count */
-}
-
-void platform_timer_eoi(void)
-{
-       *(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
-                int *min, int *sec)
-{
-       *year = *mon = *day = *hour = *min = *sec = 0;
-}
index 48e496fe1e753102811cb4064f4da6d8f0060c4f..3b7aa38254a8408b5564a260eb7a2ef30cf8d5f8 100644 (file)
@@ -60,14 +60,6 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
 
-config ARCH_HAS_ILOG2_U32
-       bool
-       default n
-
-config ARCH_HAS_ILOG2_U64
-       bool
-       default n
-
 config HUGETLB_PAGE_SIZE_VARIABLE
        bool
        depends on HUGETLB_PAGE
index 4f0c30c38e994c1ea188f811232ecc27f7b81be1..f92bdaac8976ecff13c9639743d8411289f5581f 100644 (file)
@@ -41,7 +41,7 @@ randomize_stack_top(unsigned long stack_top);
 #define elf_map                                elf32_map
 
 #undef SET_PERSONALITY
-#define SET_PERSONALITY(ex, ibcs2)     elf32_set_personality()
+#define SET_PERSONALITY(ex)    elf32_set_personality()
 
 #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
 
index ff88c48c5d19a9ba07d047b784f05dfe89e55d2f..53505bb04771811b42a74fc7d15bebb8cb25e0e4 100644 (file)
@@ -251,8 +251,8 @@ ia32_syscall_table:
        data8 compat_sys_setrlimit        /* 75 */
        data8 compat_sys_old_getrlimit
        data8 compat_sys_getrusage
-       data8 sys32_gettimeofday
-       data8 sys32_settimeofday
+       data8 compat_sys_gettimeofday
+       data8 compat_sys_settimeofday
        data8 sys32_getgroups16   /* 80 */
        data8 sys32_setgroups16
        data8 sys32_old_select
index dd0c53687a96d9f022b7a119d7f6310168c9a25c..0f15349c3c6b4ee6d56d4a22de3da87e8e7b0c69 100644 (file)
@@ -332,8 +332,8 @@ void ia64_elf32_init(struct pt_regs *regs);
 #define ELF_PLATFORM   NULL
 
 #ifdef __KERNEL__
-# define SET_PERSONALITY(EX,IBCS2)                             \
-       (current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX)
+# define SET_PERSONALITY(EX)                           \
+       (current->personality = PER_LINUX)
 #endif
 
 #define IA32_EFLAG     0x200
index bf196cbb37969ca5016b937e2074e71b48a03fff..f4430bb4bbdcc46335cf4f21579f77cd26e6afd9 100644 (file)
@@ -118,41 +118,6 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use
        return error;
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
-{
-       compat_ino_t ino;
-       int err;
-
-       if ((u64) stat->size > MAX_NON_LFS ||
-           !old_valid_dev(stat->dev) ||
-           !old_valid_dev(stat->rdev))
-               return -EOVERFLOW;
-
-       ino = stat->ino;
-       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
-               return -EOVERFLOW;
-
-       if (clear_user(ubuf, sizeof(*ubuf)))
-               return -EFAULT;
-
-       err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
-       err |= __put_user(ino, &ubuf->st_ino);
-       err |= __put_user(stat->mode, &ubuf->st_mode);
-       err |= __put_user(stat->nlink, &ubuf->st_nlink);
-       err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
-       err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
-       err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
-       err |= __put_user(stat->size, &ubuf->st_size);
-       err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
-       err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
-       err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
-       err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
-       err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
-       err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
-       err |= __put_user(stat->blksize, &ubuf->st_blksize);
-       err |= __put_user(stat->blocks, &ubuf->st_blocks);
-       return err;
-}
 
 #if PAGE_SHIFT > IA32_PAGE_SHIFT
 
@@ -1148,68 +1113,12 @@ sys32_pipe (int __user *fd)
        return retval;
 }
 
-static inline long
-get_tv32 (struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long
-put_tv32 (struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
-}
-
 asmlinkage unsigned long
 sys32_alarm (unsigned int seconds)
 {
        return alarm_setitimer(seconds);
 }
 
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-
-extern struct timezone sys_tz;
-
-asmlinkage long
-sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-asmlinkage long
-sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timeval ktv;
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_tv32(&ktv, tv))
-                       return -EFAULT;
-               kts.tv_sec = ktv.tv_sec;
-               kts.tv_nsec = ktv.tv_usec * 1000;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 struct sel_arg_struct {
        unsigned int n;
        unsigned int inp;
index 2acb6b6543c914c6293331623ed77a956918340a..86eddee029cb5238c00d4de2ef1c432f37e97e6d 100644 (file)
@@ -202,7 +202,7 @@ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
    relevant until we have real hardware to play with... */
 #define ELF_PLATFORM   NULL
 
-#define SET_PERSONALITY(ex, ibcs2)     set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex)    set_personality(PER_LINUX)
 #define elf_read_implies_exec(ex, executable_stack)                                    \
        ((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
 
index 5be4faaf5b1c49c03391bb298e6f83122d6d88ab..7103d91e1a2f92ee3db9a4d060336ee29c08d347 100644 (file)
@@ -11,7 +11,7 @@
 #undef DEBUG_PROCESS
 #ifdef DEBUG_PROCESS
 #define DPRINTK(fmt, args...)  printk("%s:%d:%s: " fmt, __FILE__, __LINE__, \
-  __FUNCTION__, ##args)
+  __func__, ##args)
 #else
 #define DPRINTK(fmt, args...)
 #endif
index 27f0ec70fba8d6f54f58677092c5318d7cee8ac0..b8046837f38496fe42c9a9645dd3fa140e975ee2 100644 (file)
@@ -105,6 +105,6 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif
index cd5fbf6f07848c3c9778aae1e8be265a92f426c4..b905744d79153be3d3170e9f81ce4e0805974d71 100644 (file)
@@ -52,6 +52,7 @@ config BCM47XX
        select SSB
        select SSB_DRIVER_MIPS
        select SSB_DRIVER_EXTIF
+       select SSB_EMBEDDED
        select SSB_PCICORE_HOSTMODE if PCI
        select GENERIC_GPIO
        select SYS_HAS_EARLY_PRINTK
index f5a53acf995a67eb7b8af311e755efc0d2db2922..9b798800258c3db159cb8ea78718d47feefe2836 100644 (file)
 #include <asm/mach-bcm47xx/bcm47xx.h>
 #include <asm/mach-bcm47xx/gpio.h>
 
-int bcm47xx_gpio_to_irq(unsigned gpio)
+#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
+static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
+#else
+static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
+#endif
+
+int gpio_request(unsigned gpio, const char *tag)
 {
-       if (ssb_bcm47xx.chipco.dev)
-               return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
-       else if (ssb_bcm47xx.extif.dev)
-               return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
-       else
+       if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
+           ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
                return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(bcm47xx_gpio_to_irq);
 
-int bcm47xx_gpio_get_value(unsigned gpio)
-{
-       if (ssb_bcm47xx.chipco.dev)
-               return ssb_chipco_gpio_in(&ssb_bcm47xx.chipco, 1 << gpio);
-       else if (ssb_bcm47xx.extif.dev)
-               return ssb_extif_gpio_in(&ssb_bcm47xx.extif, 1 << gpio);
-       else
-               return 0;
-}
-EXPORT_SYMBOL_GPL(bcm47xx_gpio_get_value);
+       if (ssb_extif_available(&ssb_bcm47xx.extif) &&
+           ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+               return -EINVAL;
 
-void bcm47xx_gpio_set_value(unsigned gpio, int value)
-{
-       if (ssb_bcm47xx.chipco.dev)
-               ssb_chipco_gpio_out(&ssb_bcm47xx.chipco,
-                                   1 << gpio,
-                                   value ? 1 << gpio : 0);
-       else if (ssb_bcm47xx.extif.dev)
-               ssb_extif_gpio_out(&ssb_bcm47xx.extif,
-                                  1 << gpio,
-                                  value ? 1 << gpio : 0);
-}
-EXPORT_SYMBOL_GPL(bcm47xx_gpio_set_value);
+       if (test_and_set_bit(gpio, gpio_in_use))
+               return -EBUSY;
 
-int bcm47xx_gpio_direction_input(unsigned gpio)
-{
-       if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES))
-               ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco,
-                                     1 << gpio, 0);
-       else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES))
-               ssb_extif_gpio_outen(&ssb_bcm47xx.extif,
-                                    1 << gpio, 0);
-       else
-               return -EINVAL;
        return 0;
 }
-EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_input);
+EXPORT_SYMBOL(gpio_request);
 
-int bcm47xx_gpio_direction_output(unsigned gpio, int value)
+void gpio_free(unsigned gpio)
 {
-       bcm47xx_gpio_set_value(gpio, value);
+       if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
+           ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+               return;
+
+       if (ssb_extif_available(&ssb_bcm47xx.extif) &&
+           ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+               return;
+
+       clear_bit(gpio, gpio_in_use);
+}
+EXPORT_SYMBOL(gpio_free);
 
-       if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES))
-               ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco,
-                                     1 << gpio, 1 << gpio);
-       else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES))
-               ssb_extif_gpio_outen(&ssb_bcm47xx.extif,
-                                    1 << gpio, 1 << gpio);
+int gpio_to_irq(unsigned gpio)
+{
+       if (ssb_chipco_available(&ssb_bcm47xx.chipco))
+               return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
+       else if (ssb_extif_available(&ssb_bcm47xx.extif))
+               return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
        else
                return -EINVAL;
-       return 0;
 }
-EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_output);
+EXPORT_SYMBOL_GPL(gpio_to_irq);
 
index 8d36f186890eaf5e4271c31ea967c0efbe18608e..2f580fa160c9f2ca33de248385ce743c8cf58365 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/types.h>
 #include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_embedded.h>
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
@@ -41,7 +42,7 @@ static void bcm47xx_machine_restart(char *command)
        printk(KERN_ALERT "Please stand by while rebooting the system...\n");
        local_irq_disable();
        /* Set the watchdog timer to reset immediately */
-       ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 1);
+       ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
        while (1)
                cpu_relax();
 }
@@ -50,7 +51,7 @@ static void bcm47xx_machine_halt(void)
 {
        /* Disable interrupts and watchdog and spin forever */
        local_irq_disable();
-       ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 0);
+       ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
        while (1)
                cpu_relax();
 }
index d1d90c9ef2fa7382fa6b65fe3e34778ad843e3c1..ef00e7f58c24f16d998430b04c899aaf4d364775 100644 (file)
@@ -11,6 +11,9 @@
 #include <linux/leds.h>
 #include <linux/mtd/physmap.h>
 #include <linux/ssb/ssb.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/gpio.h>
 #include <asm/mach-bcm47xx/bcm47xx.h>
 
 /* GPIO definitions for the WGT634U */
@@ -99,6 +102,30 @@ static struct platform_device *wgt634u_devices[] __initdata = {
        &wgt634u_gpio_leds,
 };
 
+static irqreturn_t gpio_interrupt(int irq, void *ignored)
+{
+       int state;
+
+       /* Interrupts are shared, check if the current one is
+          a GPIO interrupt. */
+       if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
+                                  SSB_CHIPCO_IRQ_GPIO))
+               return IRQ_NONE;
+
+       state = gpio_get_value(WGT634U_GPIO_RESET);
+
+       /* Interrupt are level triggered, revert the interrupt polarity
+          to clear the interrupt. */
+       gpio_polarity(WGT634U_GPIO_RESET, state);
+
+       if (!state) {
+               printk(KERN_INFO "Reset button pressed");
+               ctrl_alt_del();
+       }
+
+       return IRQ_HANDLED;
+}
+
 static int __init wgt634u_init(void)
 {
        /* There is no easy way to detect that we are running on a WGT634U
@@ -112,6 +139,19 @@ static int __init wgt634u_init(void)
            ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
             (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
                struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+
+               printk(KERN_INFO "WGT634U machine detected.\n");
+
+               if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
+                                gpio_interrupt, IRQF_SHARED,
+                                "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
+                       gpio_direction_input(WGT634U_GPIO_RESET);
+                       gpio_intmask(WGT634U_GPIO_RESET, 1);
+                       ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
+                                           SSB_CHIPCO_IRQ_GPIO,
+                                           SSB_CHIPCO_IRQ_GPIO);
+               }
+
                wgt634u_flash_data.width = mcore->flash_buswidth;
                wgt634u_flash_resource.start = mcore->flash_window;
                wgt634u_flash_resource.end = mcore->flash_window
index d956047736675db99cbe5453ce1016570ee5142b..91cbd959ab671f49782dddaee4d692a4de40371a 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <asm/system.h>
 #include <asm/mipsregs.h>
-#include <asm/debug.h>
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 
index 5e92b3a9c5b894227ffe91c0b78351650c1d3a2a..e14a2e3d8842e0a2704fb4a548a12b522cf15c49 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 #include <asm/emma2rh/emma2rh.h>
-#include <asm/debug.h>
 
 const char *get_system_type(void)
 {
index d70627de7cfe953764ae786304d0e89b73c1e178..fb9cda253ab0806f67ad6a0245c406e3d1608737 100644 (file)
@@ -35,7 +35,6 @@
 #include <asm/irq.h>
 #include <asm/reboot.h>
 #include <asm/traps.h>
-#include <asm/debug.h>
 
 #include <asm/emma2rh/emma2rh.h>
 
index f69f7acba6378542b606bed125bd409a3ec90cbf..a8eac1697b3ddcf05dccc71d42267c549cc40904 100644 (file)
@@ -247,10 +247,8 @@ extern struct mips_abi mips_abi_n32;
 
 #ifdef CONFIG_32BIT
 
-#define SET_PERSONALITY(ex, ibcs2)                                     \
+#define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
-       if (ibcs2)                                                      \
-               set_personality(PER_SVR4);                              \
        set_personality(PER_LINUX);                                     \
                                                                        \
        current->thread.abi = &mips_abi;                                \
@@ -296,7 +294,7 @@ do {                                                                        \
 #define __SET_PERSONALITY32(ex)        do { } while (0)
 #endif
 
-#define SET_PERSONALITY(ex, ibcs2)                                     \
+#define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
        clear_thread_flag(TIF_32BIT_REGS);                              \
        clear_thread_flag(TIF_32BIT_ADDR);                              \
@@ -306,9 +304,7 @@ do {                                                                        \
        else                                                            \
                current->thread.abi = &mips_abi;                        \
                                                                        \
-       if (ibcs2)                                                      \
-               set_personality(PER_SVR4);                              \
-       else if (current->personality != PER_LINUX32)                   \
+       if (current->personality != PER_LINUX32)                        \
                set_personality(PER_LINUX);                             \
 } while (0)
 
index cfc8f4d618ce517e137b7c0f57c0a65ce068bc75..d8ff4cd89ab50731d68f360f04bf5b08d9b779be 100644 (file)
@@ -9,47 +9,46 @@
 #ifndef __BCM47XX_GPIO_H
 #define __BCM47XX_GPIO_H
 
+#include <linux/ssb/ssb_embedded.h>
+#include <asm/mach-bcm47xx/bcm47xx.h>
+
 #define BCM47XX_EXTIF_GPIO_LINES       5
 #define BCM47XX_CHIPCO_GPIO_LINES      16
 
-extern int bcm47xx_gpio_to_irq(unsigned gpio);
-extern int bcm47xx_gpio_get_value(unsigned gpio);
-extern void bcm47xx_gpio_set_value(unsigned gpio, int value);
-extern int bcm47xx_gpio_direction_input(unsigned gpio);
-extern int bcm47xx_gpio_direction_output(unsigned gpio, int value);
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-       return 0;
-}
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+extern int gpio_to_irq(unsigned gpio);
 
-static inline void gpio_free(unsigned gpio)
+static inline int gpio_get_value(unsigned gpio)
 {
+       return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
 }
 
-static inline int gpio_to_irq(unsigned gpio)
+static inline void gpio_set_value(unsigned gpio, int value)
 {
-       return bcm47xx_gpio_to_irq(gpio);
+       ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
 }
 
-static inline int gpio_get_value(unsigned gpio)
+static inline int gpio_direction_input(unsigned gpio)
 {
-       return bcm47xx_gpio_get_value(gpio);
+       return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
 }
 
-static inline void gpio_set_value(unsigned gpio, int value)
+static inline int gpio_direction_output(unsigned gpio, int value)
 {
-       bcm47xx_gpio_set_value(gpio, value);
+       return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
 }
 
-static inline int gpio_direction_input(unsigned gpio)
+static int gpio_intmask(unsigned gpio, int value)
 {
-       return bcm47xx_gpio_direction_input(gpio);
+       return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
+                               value ? 1 << gpio : 0);
 }
 
-static inline int gpio_direction_output(unsigned gpio, int value)
+static int gpio_polarity(unsigned gpio, int value)
 {
-       return bcm47xx_gpio_direction_output(gpio, value);
+       return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
+                                value ? 1 << gpio : 0);
 }
 
 
index 4a2b7986b5824913bd6f990a0e03a1ee638336e7..87cd4651dda380a9438564f5b76cbd94dc9767c0 100644 (file)
@@ -5,8 +5,8 @@
  *
  * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  */
-#ifndef __ASM_MIPS_MACH_BCM947XX_WAR_H
-#define __ASM_MIPS_MACH_BCM947XX_WAR_H
+#ifndef __ASM_MIPS_MACH_BCM47XX_WAR_H
+#define __ASM_MIPS_MACH_BCM47XX_WAR_H
 
 #define R4600_V1_INDEX_ICACHEOP_WAR    0
 #define R4600_V1_HIT_CACHEOP_WAR       0
@@ -22,4 +22,4 @@
 #define R10000_LLSC_WAR                        0
 #define MIPS34K_MISSED_ITLB_WAR                0
 
-#endif /* __ASM_MIPS_MACH_BCM947XX_WAR_H */
+#endif /* __ASM_MIPS_MACH_BCM47XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-ip22/ds1286.h b/arch/mips/include/asm/mach-ip22/ds1286.h
deleted file mode 100644 (file)
index f19f1ea..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998, 2001, 03 by Ralf Baechle
- *
- * RTC routines for PC style attached Dallas chip.
- */
-#ifndef __ASM_MACH_IP22_DS1286_H
-#define __ASM_MACH_IP22_DS1286_H
-
-#include <asm/sgi/hpc3.h>
-
-#define rtc_read(reg)          (hpc3c0->rtcregs[(reg)] & 0xff)
-#define rtc_write(data, reg)   do { hpc3c0->rtcregs[(reg)] = (data); } while(0)
-
-#endif /* __ASM_MACH_IP22_DS1286_H */
diff --git a/arch/mips/include/asm/mach-ip28/ds1286.h b/arch/mips/include/asm/mach-ip28/ds1286.h
deleted file mode 100644 (file)
index 471bb9a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __ASM_MACH_IP28_DS1286_H
-#define __ASM_MACH_IP28_DS1286_H
-#include <asm/mach-ip22/ds1286.h>
-#endif /* __ASM_MACH_IP28_DS1286_H */
index 5d98a3cb85b711f6b9f8a0f1ff7cf8a82b920778..1a1f320c30d8286cff6d8d16374c9a41fa318ac3 100644 (file)
@@ -147,7 +147,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
                "       ori     %[ticket], %[ticket], 0x2000            \n"
                "       xori    %[ticket], %[ticket], 0x2000            \n"
                "       sc      %[ticket], %[ticket_ptr]                \n"
-               "       beqzl   %[ticket], 2f                           \n"
+               "       beqzl   %[ticket], 1b                           \n"
                : [ticket_ptr] "+m" (lock->lock),
                  [ticket] "=&r" (tmp));
        } else {
index 2fefb14414b7db6db1dbfd4b58719082197439ba..aa2c55e3b55ffda84dff352114a6bf904aa07580 100644 (file)
 #define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
 #endif
 
-/*
- * Revalidate the inode. This is required for proper NFS attribute caching.
- */
-
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
-       struct compat_stat tmp;
-
-       if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
-               return -EOVERFLOW;
-
-       memset(&tmp, 0, sizeof(tmp));
-       tmp.st_dev = new_encode_dev(stat->dev);
-       tmp.st_ino = stat->ino;
-       if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
-               return -EOVERFLOW;
-       tmp.st_mode = stat->mode;
-       tmp.st_nlink = stat->nlink;
-       SET_UID(tmp.st_uid, stat->uid);
-       SET_GID(tmp.st_gid, stat->gid);
-       tmp.st_rdev = new_encode_dev(stat->rdev);
-       tmp.st_size = stat->size;
-       tmp.st_atime = stat->atime.tv_sec;
-       tmp.st_mtime = stat->mtime.tv_sec;
-       tmp.st_ctime = stat->ctime.tv_sec;
-#ifdef STAT_HAVE_NSEC
-       tmp.st_atime_nsec = stat->atime.tv_nsec;
-       tmp.st_mtime_nsec = stat->mtime.tv_nsec;
-       tmp.st_ctime_nsec = stat->ctime.tv_nsec;
-#endif
-       tmp.st_blocks = stat->blocks;
-       tmp.st_blksize = stat->blksize;
-       return copy_to_user(statbuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
-}
-
 asmlinkage unsigned long
 sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
          unsigned long flags, unsigned long fd, unsigned long pgoff)
@@ -168,72 +133,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
        return sys_ftruncate(fd, merge_64(a2, a3));
 }
 
-static inline long
-get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) |
-                __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long
-put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) |
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-extern struct timezone sys_tz;
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-               return 0;
-}
-
-asmlinkage int
-sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
                            unsigned int offset_low, loff_t __user * result,
                            unsigned int origin)
index 75bb1300dd7aa0c12f7985a3986a69e9d49904f6..26760cad8b6972c4ad956a8cad81355c9d15ade7 100644 (file)
@@ -39,7 +39,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        seq_printf(m, "processor\t\t: %ld\n", n);
        sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
                cpu_data[n].options & MIPS_CPU_FPU ? "  FPU V%d.%d" : "");
-       seq_printf(m, fmt, __cpu_name[smp_processor_id()],
+       seq_printf(m, fmt, __cpu_name[n],
                                   (version >> 4) & 0x0f, version & 0x0f,
                                   (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
        seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
index dfd868b683640634f7d128f883f53165b73595fb..4ce93aa7b37259f24299791a7a793230de5a79a6 100644 (file)
@@ -522,8 +522,8 @@ static int __init rtlx_module_init(void)
                atomic_set(&channel_wqs[i].in_open, 0);
                mutex_init(&channel_wqs[i].mutex);
 
-               dev = device_create_drvdata(mt_class, NULL, MKDEV(major, i),
-                                           NULL, "%s%d", module_name, i);
+               dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+                                   "%s%d", module_name, i);
                if (IS_ERR(dev)) {
                        err = PTR_ERR(dev);
                        goto out_chrdev;
index 324c5499dec28c4b29cb529a9bc5032c71ba9aa1..e266b3aa6560fa8de6e3b0fd607bee6a714685a8 100644 (file)
@@ -214,7 +214,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_fchown
        PTR     sys_lchown
        PTR     sys_umask
-       PTR     sys32_gettimeofday
+       PTR     compat_sys_gettimeofday
        PTR     compat_sys_getrlimit            /* 6095 */
        PTR     compat_sys_getrusage
        PTR     compat_sys_sysinfo
@@ -279,7 +279,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_chroot
        PTR     sys_sync
        PTR     sys_acct
-       PTR     sys32_settimeofday
+       PTR     compat_sys_settimeofday
        PTR     compat_sys_mount                /* 6160 */
        PTR     sys_umount
        PTR     sys_swapon
index 85fedac99a578eb67e732b8762856eda3ca766c1..6c7ef8313ebd702dde4997d225f06189fdb560a0 100644 (file)
@@ -283,8 +283,8 @@ sys_call_table:
        PTR     compat_sys_setrlimit            /* 4075 */
        PTR     compat_sys_getrlimit
        PTR     compat_sys_getrusage
-       PTR     sys32_gettimeofday
-       PTR     sys32_settimeofday
+       PTR     compat_sys_gettimeofday
+       PTR     compat_sys_settimeofday
        PTR     sys_getgroups                   /* 4080 */
        PTR     sys_setgroups
        PTR     sys_ni_syscall                  /* old_select */
index afb119f35682680c2eb5eeddb20137aab7e64aa9..58738c8d754feb09bf525fe6862c62e1f6bda39a 100644 (file)
@@ -104,7 +104,7 @@ SECTIONS
        . = ALIGN(_PAGE_SIZE);
        __nosave_end = .;
 
-       . = ALIGN(32);
+       . = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT);
        .data.cacheline_aligned : {
                *(.data.cacheline_aligned)
        }
index 866881ec0cf81ed603705f8c01cebab3147def2f..8f88886feb12e147167fa7bcf61a5961bd6430cf 100644 (file)
 #endif
 
 /* Strategy function to write EEPROM after changing string entry */
-int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
+int sysctl_lasatstring(ctl_table *table,
                void *oldval, size_t *oldlenp,
                void *newval, size_t newlen)
 {
        int r;
 
-       r = sysctl_string(table, name,
-                         nlen, oldval, oldlenp, newval, newlen);
+       r = sysctl_string(table, oldval, oldlenp, newval, newlen);
        if (r < 0)
                return r;
 
@@ -113,13 +112,13 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
 #endif
 
 /* Sysctl for setting the IP addresses */
-int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
+int sysctl_lasat_intvec(ctl_table *table,
                    void *oldval, size_t *oldlenp,
                    void *newval, size_t newlen)
 {
        int r;
 
-       r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
+       r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
        if (r < 0)
                return r;
 
@@ -131,7 +130,7 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
 
 #ifdef CONFIG_DS1603
 /* Same for RTC */
-int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
+int sysctl_lasat_rtc(ctl_table *table,
                    void *oldval, size_t *oldlenp,
                    void *newval, size_t newlen)
 {
@@ -140,7 +139,7 @@ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
        rtctmp = read_persistent_clock();
        if (rtctmp < 0)
                rtctmp = 0;
-       r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
+       r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
        if (r < 0)
                return r;
        if (newval && newlen)
@@ -211,13 +210,13 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
 }
 #endif
 
-static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen,
+static int sysctl_lasat_prid(ctl_table *table,
                                     void *oldval, size_t *oldlenp,
                                     void *newval, size_t newlen)
 {
        int r;
 
-       r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
+       r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
        if (r < 0)
                return r;
        if (newval && newlen) {
index a2705895561d983f54e48f52594f1594e4166cd3..846eae9cdd051cbc2fbf6f9d007ca4fc217d152d 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/pci.h>
 
 #include <asm/bootinfo.h>
-#include <asm/debug.h>
 
 #include <asm/emma2rh/emma2rh.h>
 
index 0e160d9f07c39ae5aafd5df33dd605b6365118f7..1e6213fa7bdbc2de327b5923e95649aa0fda86e1 100644 (file)
@@ -29,8 +29,6 @@
 
 #include <asm/mach-pnx8550/pci.h>
 #include <asm/mach-pnx8550/glb.h>
-#include <asm/debug.h>
-
 
 static inline void clear_status(void)
 {
index d99591a0cdfe7abdfdeaf99a5a7218395edbfb82..772e283daa63c5115b7ca429f86164f49e87bf19 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/pci.h>
 
 #include <asm/bootinfo.h>
-#include <asm/debug.h>
 
 #include <asm/emma2rh/emma2rh.h>
 
index c7fe6ec621e68524b0e4ef5d391e7e47d43e472a..a377e9d2d029be681072a265908ba7f0f9a2dd17 100644 (file)
@@ -34,6 +34,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head;
 unsigned long PCIBIOS_MIN_IO   = 0x0000;
 unsigned long PCIBIOS_MIN_MEM  = 0;
 
+static int pci_initialized;
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
@@ -74,6 +76,42 @@ pcibios_align_resource(void *data, struct resource *res,
        res->start = start;
 }
 
+static void __devinit pcibios_scanbus(struct pci_controller *hose)
+{
+       static int next_busno;
+       static int need_domain_info;
+       struct pci_bus *bus;
+
+       if (!hose->iommu)
+               PCI_DMA_BUS_IS_PHYS = 1;
+
+       if (hose->get_busno && pci_probe_only)
+               next_busno = (*hose->get_busno)();
+
+       bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+       hose->bus = bus;
+
+       need_domain_info = need_domain_info || hose->index;
+       hose->need_domain_info = need_domain_info;
+       if (bus) {
+               next_busno = bus->subordinate + 1;
+               /* Don't allow 8-bit bus number overflow inside the hose -
+                  reserve some space for bridges. */
+               if (next_busno > 224) {
+                       next_busno = 0;
+                       need_domain_info = 1;
+               }
+
+               if (!pci_probe_only) {
+                       pci_bus_size_bridges(bus);
+                       pci_bus_assign_resources(bus);
+                       pci_enable_bridges(bus);
+               }
+       }
+}
+
+static DEFINE_MUTEX(pci_scan_mutex);
+
 void __devinit register_pci_controller(struct pci_controller *hose)
 {
        if (request_resource(&iomem_resource, hose->mem_resource) < 0)
@@ -93,6 +131,17 @@ void __devinit register_pci_controller(struct pci_controller *hose)
                printk(KERN_WARNING
                       "registering PCI controller with io_map_base unset\n");
        }
+
+       /*
+        * Scan the bus if it is register after the PCI subsystem
+        * initialization.
+        */
+       if (pci_initialized) {
+               mutex_lock(&pci_scan_mutex);
+               pcibios_scanbus(hose);
+               mutex_unlock(&pci_scan_mutex);
+       }
+
        return;
 
 out:
@@ -125,38 +174,15 @@ static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
 static int __init pcibios_init(void)
 {
        struct pci_controller *hose;
-       struct pci_bus *bus;
-       int next_busno;
-       int need_domain_info = 0;
 
        /* Scan all of the recorded PCI controllers.  */
-       for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
-
-               if (!hose->iommu)
-                       PCI_DMA_BUS_IS_PHYS = 1;
-
-               if (hose->get_busno && pci_probe_only)
-                       next_busno = (*hose->get_busno)();
-
-               bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
-               hose->bus = bus;
-               need_domain_info = need_domain_info || hose->index;
-               hose->need_domain_info = need_domain_info;
-               if (bus) {
-                       next_busno = bus->subordinate + 1;
-                       /* Don't allow 8-bit bus number overflow inside the hose -
-                          reserve some space for bridges. */
-                       if (next_busno > 224) {
-                               next_busno = 0;
-                               need_domain_info = 1;
-                       }
-               }
-       }
+       for (hose = hose_head; hose; hose = hose->next)
+               pcibios_scanbus(hose);
 
-       if (!pci_probe_only)
-               pci_assign_unassigned_resources();
        pci_fixup_irqs(common_swizzle, pcibios_map_irq);
 
+       pci_initialized = 1;
+
        return 0;
 }
 
index 8e7a46855b50ad8fc5afe81e528d2e301c833a31..1377d599f0e33ff9dcf60680aea7ff8ed07a2a5d 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/timex.h>
 
 #include <asm/mipsregs.h>
-#include <asm/debug.h>
 #include <asm/time.h>
 #include <asm/mach-rc32434/rc32434.h>
 
index 52486c4d2b019739be2db360e3cbc8b7dd1fd847..deddbf0ebe5c839175353b3f7f8cce68a594106c 100644 (file)
@@ -192,3 +192,18 @@ static int __init sgi_button_devinit(void)
 }
 
 device_initcall(sgi_button_devinit);
+
+static int __init sgi_ds1286_devinit(void)
+{
+       struct resource res;
+
+       memset(&res, 0, sizeof(res));
+       res.start = HPC3_CHIP0_BASE + offsetof(struct hpc3_regs, rtcregs);
+       res.end = res.start + sizeof(hpc3c0->rtcregs) - 1;
+       res.flags = IORESOURCE_MEM;
+
+       return IS_ERR(platform_device_register_simple("rtc-ds1286", -1,
+                                                     &res, 1));
+}
+
+device_initcall(sgi_ds1286_devinit);
index 896a1ef8482962e5376a37487693f5b87183f053..b9a931358e2391801aa0e2704ecbb8f83b991be4 100644 (file)
@@ -4,7 +4,6 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
  */
-#include <linux/ds1286.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kdev_t.h>
index 10e50549165588b13cfc5a63e17a57539f7812ba..3dcb27ec0c530b7aa4238bc4eb2cd568cd9fc794 100644 (file)
@@ -10,7 +10,6 @@
  * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org)
  */
 #include <linux/bcd.h>
-#include <linux/ds1286.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <asm/sgi/hpc3.h>
 #include <asm/sgi/ip22.h>
 
-/*
- * Note that mktime uses month from 1 to 12 while rtc_time_to_tm
- * uses 0 to 11.
- */
-unsigned long read_persistent_clock(void)
-{
-       unsigned int yrs, mon, day, hrs, min, sec;
-       unsigned int save_control;
-       unsigned long flags;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
-       hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
-
-       sec = BCD2BIN(hpc3c0->rtcregs[RTC_SECONDS] & 0xff);
-       min = BCD2BIN(hpc3c0->rtcregs[RTC_MINUTES] & 0xff);
-       hrs = BCD2BIN(hpc3c0->rtcregs[RTC_HOURS] & 0x3f);
-       day = BCD2BIN(hpc3c0->rtcregs[RTC_DATE] & 0xff);
-       mon = BCD2BIN(hpc3c0->rtcregs[RTC_MONTH] & 0x1f);
-       yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff);
-
-       hpc3c0->rtcregs[RTC_CMD] = save_control;
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       if (yrs < 45)
-               yrs += 30;
-       if ((yrs += 40) < 70)
-               yrs += 100;
-
-       return mktime(yrs + 1900, mon, day, hrs, min, sec);
-}
-
-int rtc_mips_set_time(unsigned long tim)
-{
-       struct rtc_time tm;
-       unsigned int save_control;
-       unsigned long flags;
-
-       rtc_time_to_tm(tim, &tm);
-
-       tm.tm_mon += 1;         /* tm_mon starts at zero */
-       tm.tm_year -= 40;
-       if (tm.tm_year >= 100)
-               tm.tm_year -= 100;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
-       hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
-
-       hpc3c0->rtcregs[RTC_YEAR] = BIN2BCD(tm.tm_year);
-       hpc3c0->rtcregs[RTC_MONTH] = BIN2BCD(tm.tm_mon);
-       hpc3c0->rtcregs[RTC_DATE] = BIN2BCD(tm.tm_mday);
-       hpc3c0->rtcregs[RTC_HOURS] = BIN2BCD(tm.tm_hour);
-       hpc3c0->rtcregs[RTC_MINUTES] = BIN2BCD(tm.tm_min);
-       hpc3c0->rtcregs[RTC_SECONDS] = BIN2BCD(tm.tm_sec);
-       hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0;
-
-       hpc3c0->rtcregs[RTC_CMD] = save_control;
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return 0;
-}
-
 static unsigned long dosample(void)
 {
        u32 ct0, ct1;
index 8b4e854af925b4b832dff234c0a0bcd64e2f5a42..1327c2746fb73be5cedc9484df1bfdb8ab16ce1c 100644 (file)
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/mm.h>
+#include <linux/platform_device.h>
 
 #include <asm/time.h>
 #include <asm/pgtable.h>
 #include <asm/sgialib.h>
 #include <asm/sn/ioc3.h>
-#include <asm/m48t35.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/addrs.h>
 
 #define TICK_SIZE (tick_nsec / 1000)
 
-#if 0
-static int set_rtc_mmss(unsigned long nowtime)
-{
-       int retval = 0;
-       int real_seconds, real_minutes, cmos_minutes;
-       struct m48t35_rtc *rtc;
-       nasid_t nid;
-
-       nid = get_nasid();
-       rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
-                                                       IOC3_BYTEBUS_DEV0);
-
-       rtc->control |= M48T35_RTC_READ;
-       cmos_minutes = BCD2BIN(rtc->min);
-       rtc->control &= ~M48T35_RTC_READ;
-
-       /*
-        * Since we're only adjusting minutes and seconds, don't interfere with
-        * hour overflow. This avoids messing with unknown time zones but
-        * requires your RTC not to be off by more than 15 minutes
-        */
-       real_seconds = nowtime % 60;
-       real_minutes = nowtime / 60;
-       if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-               real_minutes += 30;     /* correct for half hour time zone */
-       real_minutes %= 60;
-
-       if (abs(real_minutes - cmos_minutes) < 30) {
-               real_seconds = BIN2BCD(real_seconds);
-               real_minutes = BIN2BCD(real_minutes);
-               rtc->control |= M48T35_RTC_SET;
-               rtc->sec = real_seconds;
-               rtc->min = real_minutes;
-               rtc->control &= ~M48T35_RTC_SET;
-       } else {
-               printk(KERN_WARNING
-                      "set_rtc_mmss: can't update from %d to %d\n",
-                      cmos_minutes, real_minutes);
-               retval = -1;
-       }
-
-       return retval;
-}
-#endif
-
 /* Includes for ioc3_init().  */
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -80,37 +35,6 @@ static int set_rtc_mmss(unsigned long nowtime)
 #include <asm/sn/sn0/hubio.h>
 #include <asm/pci/bridge.h>
 
-unsigned long read_persistent_clock(void)
-{
-        unsigned int year, month, date, hour, min, sec;
-       struct m48t35_rtc *rtc;
-       nasid_t nid;
-
-       nid = get_nasid();
-       rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
-                                                       IOC3_BYTEBUS_DEV0);
-
-       rtc->control |= M48T35_RTC_READ;
-       sec = rtc->sec;
-       min = rtc->min;
-       hour = rtc->hour;
-       date = rtc->date;
-       month = rtc->month;
-       year = rtc->year;
-       rtc->control &= ~M48T35_RTC_READ;
-
-        sec = BCD2BIN(sec);
-        min = BCD2BIN(min);
-        hour = BCD2BIN(hour);
-        date = BCD2BIN(date);
-        month = BCD2BIN(month);
-        year = BCD2BIN(year);
-
-        year += 1970;
-
-        return mktime(year, month, date, hour, min, sec);
-}
-
 static void enable_rt_irq(unsigned int irq)
 {
 }
@@ -286,6 +210,7 @@ void __cpuinit cpu_time_init(void)
 
 void __cpuinit hub_rtc_init(cnodeid_t cnode)
 {
+
        /*
         * We only need to initialize the current node.
         * If this is not the current node then it is a cpuless
@@ -301,3 +226,23 @@ void __cpuinit hub_rtc_init(cnodeid_t cnode)
                LOCAL_HUB_S(PI_RT_PEND_B, 0);
        }
 }
+
+static int __init sgi_ip27_rtc_devinit(void)
+{
+       struct resource res;
+
+       memset(&res, 0, sizeof(res));
+       res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base +
+                             IOC3_BYTEBUS_DEV0);
+       res.end = res.start + 32767;
+       res.flags = IORESOURCE_MEM;
+
+       return IS_ERR(platform_device_register_simple("rtc-m48t35", -1,
+                                                     &res, 1));
+}
+
+/*
+ * kludge make this a device_initcall after ioc3 resource conflicts
+ * are resolved
+ */
+late_initcall(sgi_ip27_rtc_devinit);
index 3d63721e0e804e117cb0580837014c016856f66c..511e9ff2acfd997751d1b86b80e7165e262052a9 100644 (file)
@@ -90,6 +90,22 @@ static __init int sgio2btns_devinit(void)
 
 device_initcall(sgio2btns_devinit);
 
+static struct resource sgio2_cmos_rsrc[] = {
+       {
+               .start = 0x70,
+               .end   = 0x71,
+               .flags = IORESOURCE_IO
+       }
+};
+
+static __init int sgio2_cmos_devinit(void)
+{
+       return IS_ERR(platform_device_register_simple("rtc_cmos", -1,
+                                                     sgio2_cmos_rsrc, 1));
+}
+
+device_initcall(sgio2_cmos_devinit);
+
 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2");
index 1024bf40bd9e79f1c63dd79f7be8289371e89caf..c5a5d4a31b4b42f1c7d3c9a2f45cbbe88e16bf01 100644 (file)
@@ -62,11 +62,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
 }
 #endif
 
-unsigned long read_persistent_clock(void)
-{
-       return mc146818_get_cmos_time();
-}
-
 /* An arbitrary time; this can be decreased if reliability looks good */
 #define WAIT_MS 10
 
index 66e3e3fb311f9a413ffb3dbc58aa9174fe101fe5..637a194e5cd5f95e0ee2de2687ddbab05ac45cec 100644 (file)
@@ -576,8 +576,7 @@ static int __init sbprof_tb_init(void)
 
        tb_class = tbc;
 
-       dev = device_create_drvdata(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0),
-                                   NULL, "tb");
+       dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb");
        if (IS_ERR(dev)) {
                err = PTR_ERR(dev);
                goto out_class;
index ecb10a4f63c6af15324cb7343951701b04aaba1f..f61692d2b557edcc51691148182b3750b373ccb9 100644 (file)
@@ -85,7 +85,7 @@ struct elf_prpsinfo32
  * could set a processor dependent flag in the thread_struct.
  */
 
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
        set_thread_flag(TIF_32BIT); \
        current->thread.map_base = DEFAULT_MAP_BASE32; \
        current->thread.task_size = DEFAULT_TASK_SIZE32 \
index 71efd6a28e2a39b60a3151836d50facd9594984f..0838155b7a88229df24188a9f0dc74b2facf1162 100644 (file)
@@ -179,111 +179,6 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
        return ret;
 }
 
-static int
-put_compat_timeval(struct compat_timeval __user *u, struct timeval *t)
-{
-       struct compat_timeval t32;
-       t32.tv_sec = t->tv_sec;
-       t32.tv_usec = t->tv_usec;
-       return copy_to_user(u, &t32, sizeof t32);
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-    extern void do_gettimeofday(struct timeval *tv);
-
-    if (tv) {
-           struct timeval ktv;
-           do_gettimeofday(&ktv);
-           if (put_compat_timeval(tv, &ktv))
-                   return -EFAULT;
-    }
-    if (tz) {
-           extern struct timezone sys_tz;
-           if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                   return -EFAULT;
-    }
-    return 0;
-}
-
-asmlinkage 
-int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
-       compat_ino_t ino;
-       int err;
-
-       if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
-           !new_valid_dev(stat->rdev))
-               return -EOVERFLOW;
-
-       ino = stat->ino;
-       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
-               return -EOVERFLOW;
-
-       err  = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-       err |= put_user(ino, &statbuf->st_ino);
-       err |= put_user(stat->mode, &statbuf->st_mode);
-       err |= put_user(stat->nlink, &statbuf->st_nlink);
-       err |= put_user(0, &statbuf->st_reserved1);
-       err |= put_user(0, &statbuf->st_reserved2);
-       err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
-       err |= put_user(stat->size, &statbuf->st_size);
-       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-       err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-       err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-       err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-       err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-       err |= put_user(stat->blksize, &statbuf->st_blksize);
-       err |= put_user(stat->blocks, &statbuf->st_blocks);
-       err |= put_user(0, &statbuf->__unused1);
-       err |= put_user(0, &statbuf->__unused2);
-       err |= put_user(0, &statbuf->__unused3);
-       err |= put_user(0, &statbuf->__unused4);
-       err |= put_user(0, &statbuf->__unused5);
-       err |= put_user(0, &statbuf->st_fstype); /* not avail */
-       err |= put_user(0, &statbuf->st_realdev); /* not avail */
-       err |= put_user(0, &statbuf->st_basemode); /* not avail */
-       err |= put_user(0, &statbuf->st_spareshort);
-       err |= put_user(stat->uid, &statbuf->st_uid);
-       err |= put_user(stat->gid, &statbuf->st_gid);
-       err |= put_user(0, &statbuf->st_spare4[0]);
-       err |= put_user(0, &statbuf->st_spare4[1]);
-       err |= put_user(0, &statbuf->st_spare4[2]);
-
-       return err;
-}
-
 /*** copied from mips64 ***/
 /*
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
index 6b5ac38f5a9916017473d3174bb6f3d047f72cb8..c7e59f548817fb36554954d663bfedcdf5e3b2f6 100644 (file)
        ENTRY_COMP(getrlimit)
        ENTRY_COMP(getrusage)
        /* struct timeval and timezone are maybe?? consistent wide and narrow */
-       ENTRY_DIFF(gettimeofday)
-       ENTRY_DIFF(settimeofday)
+       ENTRY_COMP(gettimeofday)
+       ENTRY_COMP(settimeofday)
        ENTRY_SAME(getgroups)           /* 80 */
        ENTRY_SAME(setgroups)
        /* struct socketaddr... */
index f5f83ee6041126832b6c0f514b47e082759aac0c..380baa1780e9197b060ce1594aa098340d4da538 100644 (file)
@@ -418,8 +418,11 @@ config PPC_64K_PAGES
 
 config FORCE_MAX_ZONEORDER
        int "Maximum zone order"
+       range 9 64 if PPC_64K_PAGES
        default "9" if PPC_64K_PAGES
+       range 13 64 if PPC64 && !PPC_64K_PAGES
        default "13" if PPC64 && !PPC_64K_PAGES
+       range 11 64
        default "11"
        help
          The kernel memory allocator divides physically contiguous memory
@@ -809,6 +812,19 @@ config PIN_TLB
 endmenu
 
 if PPC64
+config RELOCATABLE
+       bool "Build a relocatable kernel"
+       help
+         This builds a kernel image that is capable of running anywhere
+         in the RMA (real memory area) at any 16k-aligned base address.
+         The kernel is linked as a position-independent executable (PIE)
+         and contains dynamic relocations which are processed early
+         in the bootup process.
+
+         One use is for the kexec on panic case where the recovery kernel
+         must live at a different physical address than the primary
+         kernel.
+
 config PAGE_OFFSET
        hex
        default "0xc000000000000000"
index 4ebc52a19f0ab4e9883a3621882744d5f69e0dcc..15eb27861fc713c1b02995fd030bc139652b24d2 100644 (file)
@@ -51,6 +51,11 @@ config FTR_FIXUP_SELFTEST
        depends on DEBUG_KERNEL
        default n
 
+config MSI_BITMAP_SELFTEST
+       bool "Run self-tests of the MSI bitmap code."
+       depends on DEBUG_KERNEL
+       default n
+
 config XMON
        bool "Include xmon kernel debugger"
        depends on DEBUG_KERNEL
index c6be19e9ceae99dd6f0d6a47f66e44634a71e3bb..24dd1a37f8fb93268b120ac844bd62880eb2a7de 100644 (file)
@@ -63,7 +63,9 @@ override CC   += -m$(CONFIG_WORD_SIZE)
 override AR    := GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
 endif
 
-LDFLAGS_vmlinux        := -Bstatic
+LDFLAGS_vmlinux-yy := -Bstatic
+LDFLAGS_vmlinux-$(CONFIG_PPC64)$(CONFIG_RELOCATABLE) := -pie
+LDFLAGS_vmlinux        := $(LDFLAGS_vmlinux-yy)
 
 CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none  -mcall-aixdesc
 CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
@@ -102,7 +104,10 @@ endif
 KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
 
 # No SPE instruction when building kernel
+# (We use all available options to help semi-broken compilers)
 KBUILD_CFLAGS += $(call cc-option,-mno-spe)
+KBUILD_CFLAGS += $(call cc-option,-mspe=no)
+KBUILD_CFLAGS += $(call cc-option,-mabi=no-spe)
 
 # Enable unit-at-a-time mode when possible. It shrinks the
 # kernel considerably.
index 65d1a8454d2cfb11e54ffa3082c16bc3316bd4da..aac1406ccba5cb6394cdacf4837d846e4d35e56a 100644 (file)
@@ -310,8 +310,11 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb
 $(obj)/vmlinux.strip: vmlinux
        $(STRIP) -s -R .comment $< -o $@
 
+# The iseries hypervisor won't take an ET_DYN executable, so this
+# changes the type (byte 17) in the file to ET_EXEC (2).
 $(obj)/zImage.iseries: vmlinux
        $(STRIP) -s -R .comment $< -o $@
+       printf "\x02" | dd of=$@ conv=notrunc bs=1 seek=17
 
 $(obj)/uImage: vmlinux $(wrapperbits)
        $(call if_changed,wrap,uboot)
index b1e5611b2ab1d639edd67346ca50f88d625b9629..dcc9ab2ca823fff000dccf638c3c7caab421500e 100644 (file)
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- * Usage: addnote zImage
+ * Usage: addnote zImage [note.elf]
+ *
+ * If note.elf is supplied, it is the name of an ELF file that contains
+ * an RPA note to use instead of the built-in one.  Alternatively, the
+ * note.elf file may be empty, in which case the built-in RPA note is
+ * used (this is to simplify how this is invoked from the wrapper script).
  */
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,27 +48,29 @@ char rpaname[] = "IBM,RPA-Client-Config";
  */
 #define N_RPA_DESCR    8
 unsigned int rpanote[N_RPA_DESCR] = {
-       0,                      /* lparaffinity */
-       64,                     /* min_rmo_size */
+       1,                      /* lparaffinity */
+       128,                    /* min_rmo_size */
        0,                      /* min_rmo_percent */
-       40,                     /* max_pft_size */
+       46,                     /* max_pft_size */
        1,                      /* splpar */
        -1,                     /* min_load */
-       0,                      /* new_mem_def */
-       1,                      /* ignore_my_client_config */
+       1,                      /* new_mem_def */
+       0,                      /* ignore_my_client_config */
 };
 
 #define ROUNDUP(len)   (((len) + 3) & ~3)
 
 unsigned char buf[512];
+unsigned char notebuf[512];
 
-#define GET_16BE(off)  ((buf[off] << 8) + (buf[(off)+1]))
-#define GET_32BE(off)  ((GET_16BE(off) << 16) + GET_16BE((off)+2))
+#define GET_16BE(b, off)       (((b)[off] << 8) + ((b)[(off)+1]))
+#define GET_32BE(b, off)       ((GET_16BE((b), (off)) << 16) + \
+                                GET_16BE((b), (off)+2))
 
-#define PUT_16BE(off, v)       (buf[off] = ((v) >> 8) & 0xff, \
-                                buf[(off) + 1] = (v) & 0xff)
-#define PUT_32BE(off, v)       (PUT_16BE((off), (v) >> 16), \
-                                PUT_16BE((off) + 2, (v)))
+#define PUT_16BE(b, off, v)    ((b)[off] = ((v) >> 8) & 0xff, \
+                                (b)[(off) + 1] = (v) & 0xff)
+#define PUT_32BE(b, off, v)    (PUT_16BE((b), (off), (v) >> 16), \
+                                PUT_16BE((b), (off) + 2, (v)))
 
 /* Structure of an ELF file */
 #define E_IDENT                0       /* ELF header */
@@ -88,15 +95,71 @@ unsigned char buf[512];
 
 unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
 
+unsigned char *read_rpanote(const char *fname, int *nnp)
+{
+       int notefd, nr, i;
+       int ph, ps, np;
+       int note, notesize;
+
+       notefd = open(fname, O_RDONLY);
+       if (notefd < 0) {
+               perror(fname);
+               exit(1);
+       }
+       nr = read(notefd, notebuf, sizeof(notebuf));
+       if (nr < 0) {
+               perror("read note");
+               exit(1);
+       }
+       if (nr == 0)            /* empty file */
+               return NULL;
+       if (nr < E_HSIZE ||
+           memcmp(&notebuf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0 ||
+           notebuf[E_IDENT+EI_CLASS] != ELFCLASS32 ||
+           notebuf[E_IDENT+EI_DATA] != ELFDATA2MSB)
+               goto notelf;
+       close(notefd);
+
+       /* now look for the RPA-note */
+       ph = GET_32BE(notebuf, E_PHOFF);
+       ps = GET_16BE(notebuf, E_PHENTSIZE);
+       np = GET_16BE(notebuf, E_PHNUM);
+       if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+               goto notelf;
+
+       for (i = 0; i < np; ++i, ph += ps) {
+               if (GET_32BE(notebuf, ph + PH_TYPE) != PT_NOTE)
+                       continue;
+               note = GET_32BE(notebuf, ph + PH_OFFSET);
+               notesize = GET_32BE(notebuf, ph + PH_FILESZ);
+               if (notesize < 34 || note + notesize > nr)
+                       continue;
+               if (GET_32BE(notebuf, note) != strlen(rpaname) + 1 ||
+                   GET_32BE(notebuf, note + 8) != 0x12759999 ||
+                   strcmp((char *)&notebuf[note + 12], rpaname) != 0)
+                       continue;
+               /* looks like an RPA note, return it */
+               *nnp = notesize;
+               return &notebuf[note];
+       }
+       /* no RPA note found */
+       return NULL;
+
+ notelf:
+       fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", fname);
+       exit(1);
+}
+
 int
 main(int ac, char **av)
 {
        int fd, n, i;
        int ph, ps, np;
        int nnote, nnote2, ns;
+       unsigned char *rpap;
 
-       if (ac != 2) {
-               fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+       if (ac != 2 && ac != 3) {
+               fprintf(stderr, "Usage: %s elf-file [rpanote.elf]\n", av[0]);
                exit(1);
        }
        fd = open(av[1], O_RDWR);
@@ -107,6 +170,7 @@ main(int ac, char **av)
 
        nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr);
        nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote);
+       rpap = NULL;
 
        n = read(fd, buf, sizeof(buf));
        if (n < 0) {
@@ -124,16 +188,19 @@ main(int ac, char **av)
                exit(1);
        }
 
-       ph = GET_32BE(E_PHOFF);
-       ps = GET_16BE(E_PHENTSIZE);
-       np = GET_16BE(E_PHNUM);
+       if (ac == 3)
+               rpap = read_rpanote(av[2], &nnote2);
+
+       ph = GET_32BE(buf, E_PHOFF);
+       ps = GET_16BE(buf, E_PHENTSIZE);
+       np = GET_16BE(buf, E_PHNUM);
        if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
                goto notelf;
        if (ph + (np + 2) * ps + nnote + nnote2 > n)
                goto nospace;
 
        for (i = 0; i < np; ++i) {
-               if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+               if (GET_32BE(buf, ph + PH_TYPE) == PT_NOTE) {
                        fprintf(stderr, "%s already has a note entry\n",
                                av[1]);
                        exit(0);
@@ -148,37 +215,42 @@ main(int ac, char **av)
 
        /* fill in the program header entry */
        ns = ph + 2 * ps;
-       PUT_32BE(ph + PH_TYPE, PT_NOTE);
-       PUT_32BE(ph + PH_OFFSET, ns);
-       PUT_32BE(ph + PH_FILESZ, nnote);
+       PUT_32BE(buf, ph + PH_TYPE, PT_NOTE);
+       PUT_32BE(buf, ph + PH_OFFSET, ns);
+       PUT_32BE(buf, ph + PH_FILESZ, nnote);
 
        /* fill in the note area we point to */
        /* XXX we should probably make this a proper section */
-       PUT_32BE(ns, strlen(arch) + 1);
-       PUT_32BE(ns + 4, N_DESCR * 4);
-       PUT_32BE(ns + 8, 0x1275);
+       PUT_32BE(buf, ns, strlen(arch) + 1);
+       PUT_32BE(buf, ns + 4, N_DESCR * 4);
+       PUT_32BE(buf, ns + 8, 0x1275);
        strcpy((char *) &buf[ns + 12], arch);
        ns += 12 + strlen(arch) + 1;
        for (i = 0; i < N_DESCR; ++i, ns += 4)
-               PUT_32BE(ns, descr[i]);
+               PUT_32BE(buf, ns, descr[i]);
 
        /* fill in the second program header entry and the RPA note area */
        ph += ps;
-       PUT_32BE(ph + PH_TYPE, PT_NOTE);
-       PUT_32BE(ph + PH_OFFSET, ns);
-       PUT_32BE(ph + PH_FILESZ, nnote2);
+       PUT_32BE(buf, ph + PH_TYPE, PT_NOTE);
+       PUT_32BE(buf, ph + PH_OFFSET, ns);
+       PUT_32BE(buf, ph + PH_FILESZ, nnote2);
 
        /* fill in the note area we point to */
-       PUT_32BE(ns, strlen(rpaname) + 1);
-       PUT_32BE(ns + 4, sizeof(rpanote));
-       PUT_32BE(ns + 8, 0x12759999);
-       strcpy((char *) &buf[ns + 12], rpaname);
-       ns += 12 + ROUNDUP(strlen(rpaname) + 1);
-       for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
-               PUT_32BE(ns, rpanote[i]);
+       if (rpap) {
+               /* RPA note supplied in file, just copy the whole thing over */
+               memcpy(buf + ns, rpap, nnote2);
+       } else {
+               PUT_32BE(buf, ns, strlen(rpaname) + 1);
+               PUT_32BE(buf, ns + 4, sizeof(rpanote));
+               PUT_32BE(buf, ns + 8, 0x12759999);
+               strcpy((char *) &buf[ns + 12], rpaname);
+               ns += 12 + ROUNDUP(strlen(rpaname) + 1);
+               for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
+                       PUT_32BE(buf, ns, rpanote[i]);
+       }
 
        /* Update the number of program headers */
-       PUT_16BE(E_PHNUM, np + 2);
+       PUT_16BE(buf, E_PHNUM, np + 2);
 
        /* write back */
        lseek(fd, (long) 0, SEEK_SET);
index d607fdb8df8df8a2df1ecaef98b665e4355063b2..6ddf9ecac669861511d9dbbeed7b4b7b831d1883 100644 (file)
@@ -5,21 +5,5 @@
 #
 DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
        checks.c
-DTC_EXTRA = dtc.h srcpos.h
-DTC_LEXFILES = dtc-lexer.l
-DTC_BISONFILES = dtc-parser.y
-
-DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c)
-DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c)
-DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h)
-
-DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS)
-DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES)
+DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
 DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
-
-DTC_CLEANFILES = $(DTC_GEN_ALL)
-
-# We assume the containing Makefile system can do auto-dependencies for most
-# things, but we supply the dependencies on generated header files explicitly
-
-$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
index 2ce961cd414d71f71993b5a15fd3931cc69833a4..95485796f253ffb0d2c413e50acf650fe397aece 100644 (file)
@@ -242,6 +242,42 @@ static void check_duplicate_property_names(struct check *c, struct node *dt,
 }
 NODE_CHECK(duplicate_property_names, NULL, ERROR);
 
+#define LOWERCASE      "abcdefghijklmnopqrstuvwxyz"
+#define UPPERCASE      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define DIGITS         "0123456789"
+#define PROPNODECHARS  LOWERCASE UPPERCASE DIGITS ",._+*#?-"
+
+static void check_node_name_chars(struct check *c, struct node *dt,
+                                 struct node *node)
+{
+       int n = strspn(node->name, c->data);
+
+       if (n < strlen(node->name))
+               FAIL(c, "Bad character '%c' in node %s",
+                    node->name[n], node->fullpath);
+}
+NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
+
+static void check_node_name_format(struct check *c, struct node *dt,
+                                  struct node *node)
+{
+       if (strchr(get_unitname(node), '@'))
+               FAIL(c, "Node %s has multiple '@' characters in name",
+                    node->fullpath);
+}
+NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
+
+static void check_property_name_chars(struct check *c, struct node *dt,
+                                     struct node *node, struct property *prop)
+{
+       int n = strspn(prop->name, c->data);
+
+       if (n < strlen(prop->name))
+               FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
+                    prop->name[n], prop->name, node->fullpath);
+}
+PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
+
 static void check_explicit_phandles(struct check *c, struct node *root,
                                          struct node *node)
 {
@@ -280,16 +316,29 @@ NODE_CHECK(explicit_phandles, NULL, ERROR);
 static void check_name_properties(struct check *c, struct node *root,
                                  struct node *node)
 {
-       struct property *prop;
+       struct property **pp, *prop = NULL;
+
+       for (pp = &node->proplist; *pp; pp = &((*pp)->next))
+               if (streq((*pp)->name, "name")) {
+                       prop = *pp;
+                       break;
+               }
 
-       prop = get_property(node, "name");
        if (!prop)
                return; /* No name property, that's fine */
 
        if ((prop->val.len != node->basenamelen+1)
-           || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
+           || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
                FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
                     " of base node name)", node->fullpath, prop->val.val);
+       } else {
+               /* The name property is correct, and therefore redundant.
+                * Delete it */
+               *pp = prop->next;
+               free(prop->name);
+               data_free(prop->val);
+               free(prop);
+       }
 }
 CHECK_IS_STRING(name_is_string, "name", ERROR);
 NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
@@ -301,23 +350,23 @@ NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
 static void fixup_phandle_references(struct check *c, struct node *dt,
                                     struct node *node, struct property *prop)
 {
-      struct marker *m = prop->val.markers;
-      struct node *refnode;
-      cell_t phandle;
-
-      for_each_marker_of_type(m, REF_PHANDLE) {
-             assert(m->offset + sizeof(cell_t) <= prop->val.len);
-
-             refnode = get_node_by_ref(dt, m->ref);
-             if (! refnode) {
-                     FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-                          m->ref);
-                     continue;
-             }
-
-             phandle = get_node_phandle(dt, refnode);
-             *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
-      }
+       struct marker *m = prop->val.markers;
+       struct node *refnode;
+       cell_t phandle;
+
+       for_each_marker_of_type(m, REF_PHANDLE) {
+               assert(m->offset + sizeof(cell_t) <= prop->val.len);
+
+               refnode = get_node_by_ref(dt, m->ref);
+               if (! refnode) {
+                       FAIL(c, "Reference to non-existent node or label \"%s\"\n",
+                            m->ref);
+                       continue;
+               }
+
+               phandle = get_node_phandle(dt, refnode);
+               *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
+       }
 }
 CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
       &duplicate_node_names, &explicit_phandles);
@@ -498,6 +547,7 @@ TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
 
 static struct check *check_table[] = {
        &duplicate_node_names, &duplicate_property_names,
+       &node_name_chars, &node_name_format, &property_name_chars,
        &name_is_string, &name_properties,
        &explicit_phandles,
        &phandle_references, &path_references,
@@ -511,10 +561,7 @@ static struct check *check_table[] = {
        &obsolete_chosen_interrupt_controller,
 };
 
-int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
-
-void process_checks(int force, struct boot_info *bi,
-                   int checkflag, int outversion, int boot_cpuid_phys)
+void process_checks(int force, struct boot_info *bi)
 {
        struct node *dt = bi->dt;
        int i;
@@ -537,214 +584,4 @@ void process_checks(int force, struct boot_info *bi,
                                "output forced\n");
                }
        }
-
-       if (checkflag) {
-               if (error) {
-                       fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
-               } else {
-                       if (!check_semantics(bi->dt, outversion,
-                                            boot_cpuid_phys))
-                               fprintf(stderr, "Warning: Input tree has semantic errors\n");
-               }
-       }
-}
-
-/*
- * Semantic check functions
- */
-
-#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
-#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
-
-#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
-
-#define CHECK_HAVE(node, propname) \
-       do { \
-               if (! (prop = get_property((node), (propname)))) \
-                       DO_ERR("Missing \"%s\" property in %s\n", (propname), \
-                               (node)->fullpath); \
-       } while (0);
-
-#define CHECK_HAVE_WARN(node, propname) \
-       do { \
-               if (! (prop  = get_property((node), (propname)))) \
-                       WARNMSG("%s has no \"%s\" property\n", \
-                               (node)->fullpath, (propname)); \
-       } while (0)
-
-#define CHECK_HAVE_STRING(node, propname) \
-       do { \
-               CHECK_HAVE((node), (propname)); \
-               if (prop && !data_is_one_string(prop->val)) \
-                       DO_ERR("\"%s\" property in %s is not a string\n", \
-                               (propname), (node)->fullpath); \
-       } while (0)
-
-#define CHECK_HAVE_STREQ(node, propname, value) \
-       do { \
-               CHECK_HAVE_STRING((node), (propname)); \
-               if (prop && !streq(prop->val.val, (value))) \
-                       DO_ERR("%s has wrong %s, %s (should be %s\n", \
-                               (node)->fullpath, (propname), \
-                               prop->val.val, (value)); \
-       } while (0)
-
-#define CHECK_HAVE_ONECELL(node, propname) \
-       do { \
-               CHECK_HAVE((node), (propname)); \
-               if (prop && (prop->val.len != sizeof(cell_t))) \
-                       DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
-       } while (0)
-
-#define CHECK_HAVE_WARN_ONECELL(node, propname) \
-       do { \
-               CHECK_HAVE_WARN((node), (propname)); \
-               if (prop && (prop->val.len != sizeof(cell_t))) \
-                       DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
-       } while (0)
-
-#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
-       do { \
-               struct node *ref; \
-               CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
-               if (prop) {\
-                       cell_t phandle = propval_cell(prop); \
-                       if ((phandle == 0) || (phandle == -1)) { \
-                               DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
-                       } else { \
-                               ref = get_node_by_phandle((root), propval_cell(prop)); \
-                               if (! ref) \
-                                       DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
-                       } \
-               } \
-       } while (0)
-
-#define CHECK_HAVE_WARN_STRING(node, propname) \
-       do { \
-               CHECK_HAVE_WARN((node), (propname)); \
-               if (prop && !data_is_one_string(prop->val)) \
-                       DO_ERR("\"%s\" property in %s is not a string\n", \
-                               (propname), (node)->fullpath); \
-       } while (0)
-
-static int check_root(struct node *root)
-{
-       struct property *prop;
-       int ok = 1;
-
-       CHECK_HAVE_STRING(root, "model");
-       CHECK_HAVE_WARN(root, "compatible");
-
-       return ok;
-}
-
-static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
-{
-       struct node *cpus, *cpu;
-       struct property *prop;
-       struct node *bootcpu = NULL;
-       int ok = 1;
-
-       cpus = get_subnode(root, "cpus");
-       if (! cpus) {
-               ERRMSG("Missing /cpus node\n");
-               return 0;
-       }
-
-       if (cpus->addr_cells != 1)
-               DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
-                      cpus->fullpath, cpus->addr_cells);
-       if (cpus->size_cells != 0)
-               DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
-                      cpus->fullpath, cpus->size_cells);
-
-       for_each_child(cpus, cpu) {
-               CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
-
-               CHECK_HAVE_ONECELL(cpu, "reg");
-               if (prop) {
-                       cell_t unitnum;
-                       char *eptr;
-
-                       unitnum = strtol(get_unitname(cpu), &eptr, 16);
-                       if (*eptr) {
-                               WARNMSG("%s has bad format unit name %s (should be CPU number\n",
-                                       cpu->fullpath, get_unitname(cpu));
-                       } else if (unitnum != propval_cell(prop)) {
-                               WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
-                                      cpu->fullpath, get_unitname(cpu),
-                                      propval_cell(prop));
-                       }
-               }
-
-/*             CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
-/*             CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
-               CHECK_HAVE_ONECELL(cpu, "d-cache-size");
-               CHECK_HAVE_ONECELL(cpu, "i-cache-size");
-
-               CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
-               CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
-
-               prop = get_property(cpu, "linux,boot-cpu");
-               if (prop) {
-                       if (prop->val.len)
-                               WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
-                                       cpu->fullpath);
-                       if (bootcpu)
-                               DO_ERR("Multiple boot cpus (%s and %s)\n",
-                                      bootcpu->fullpath, cpu->fullpath);
-                       else
-                               bootcpu = cpu;
-               }
-       }
-
-       if (outversion < 2) {
-               if (! bootcpu)
-                       WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
-       } else {
-               if (bootcpu)
-                       WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
-               if (boot_cpuid_phys == 0xfeedbeef)
-                       WARNMSG("physical boot CPU not set.  Use -b option to set\n");
-       }
-
-       return ok;
-}
-
-static int check_memory(struct node *root)
-{
-       struct node *mem;
-       struct property *prop;
-       int nnodes = 0;
-       int ok = 1;
-
-       for_each_child(root, mem) {
-               if (! strneq(mem->name, "memory", mem->basenamelen))
-                       continue;
-
-               nnodes++;
-
-               CHECK_HAVE_STREQ(mem, "device_type", "memory");
-               CHECK_HAVE(mem, "reg");
-       }
-
-       if (nnodes == 0) {
-               ERRMSG("No memory nodes\n");
-               return 0;
-       }
-
-       return ok;
-}
-
-int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
-{
-       int ok = 1;
-
-       ok = ok && check_root(dt);
-       ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
-       ok = ok && check_memory(dt);
-       if (! ok)
-               return 0;
-
-       return 1;
 }
index a94718c731a95256d92e3ea1fbf63077aebd917a..dd2e3d39d4c1ba941f58c0e676cb52fc6bac93a4 100644 (file)
@@ -32,8 +32,6 @@ void data_free(struct data d)
                m = nm;
        }
 
-       assert(!d.val || d.asize);
-
        if (d.val)
                free(d.val);
 }
@@ -43,9 +41,6 @@ struct data data_grow_for(struct data d, int xlen)
        struct data nd;
        int newsize;
 
-       /* we must start with an allocated datum */
-       assert(!d.val || d.asize);
-
        if (xlen == 0)
                return d;
 
@@ -56,11 +51,8 @@ struct data data_grow_for(struct data d, int xlen)
        while ((d.len + xlen) > newsize)
                newsize *= 2;
 
-       nd.asize = newsize;
        nd.val = xrealloc(d.val, newsize);
 
-       assert(nd.asize >= (d.len + xlen));
-
        return nd;
 }
 
@@ -83,16 +75,11 @@ static char get_oct_char(const char *s, int *i)
        long val;
 
        x[3] = '\0';
-       x[0] = s[(*i)];
-       if (x[0]) {
-               x[1] = s[(*i)+1];
-               if (x[1])
-                       x[2] = s[(*i)+2];
-       }
+       strncpy(x, s + *i, 3);
 
        val = strtol(x, &endx, 8);
-       if ((endx - x) == 0)
-               fprintf(stderr, "Empty \\nnn escape\n");
+
+       assert(endx > x);
 
        (*i) += endx - x;
        return val;
@@ -105,13 +92,11 @@ static char get_hex_char(const char *s, int *i)
        long val;
 
        x[2] = '\0';
-       x[0] = s[(*i)];
-       if (x[0])
-               x[1] = s[(*i)+1];
+       strncpy(x, s + *i, 2);
 
        val = strtol(x, &endx, 16);
-       if ((endx - x) == 0)
-               fprintf(stderr, "Empty \\x escape\n");
+       if (!(endx  > x))
+               die("\\x used with no following hex digits\n");
 
        (*i) += endx - x;
        return val;
@@ -182,14 +167,29 @@ struct data data_copy_escape_string(const char *s, int len)
        return d;
 }
 
-struct data data_copy_file(FILE *f, size_t len)
+struct data data_copy_file(FILE *f, size_t maxlen)
 {
-       struct data d;
+       struct data d = empty_data;
 
-       d = data_grow_for(empty_data, len);
+       while (!feof(f) && (d.len < maxlen)) {
+               size_t chunksize, ret;
 
-       d.len = len;
-       fread(d.val, len, 1, f);
+               if (maxlen == -1)
+                       chunksize = 4096;
+               else
+                       chunksize = maxlen - d.len;
+
+               d = data_grow_for(d, chunksize);
+               ret = fread(d.val + d.len, 1, chunksize, f);
+
+               if (ferror(f))
+                       die("Error reading file into data: %s", strerror(errno));
+
+               if (d.len + ret < d.len)
+                       die("Overflow reading file into data\n");
+
+               d.len += ret;
+       }
 
        return d;
 }
@@ -247,7 +247,7 @@ struct data data_merge(struct data d1, struct data d2)
 
 struct data data_append_cell(struct data d, cell_t word)
 {
-       cell_t beword = cpu_to_be32(word);
+       cell_t beword = cpu_to_fdt32(word);
 
        return data_append_data(d, &beword, sizeof(beword));
 }
@@ -256,15 +256,15 @@ struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
 {
        struct fdt_reserve_entry bere;
 
-       bere.address = cpu_to_be64(re->address);
-       bere.size = cpu_to_be64(re->size);
+       bere.address = cpu_to_fdt64(re->address);
+       bere.size = cpu_to_fdt64(re->size);
 
        return data_append_data(d, &bere, sizeof(bere));
 }
 
-struct data data_append_addr(struct data d, u64 addr)
+struct data data_append_addr(struct data d, uint64_t addr)
 {
-       u64 beaddr = cpu_to_be64(addr);
+       uint64_t beaddr = cpu_to_fdt64(addr);
 
        return data_append_data(d, &beaddr, sizeof(beaddr));
 }
index c811b221b31e26ac827955918d53000ccf9e8ea6..44dbfd3f097650c139476571348655066a1006c2 100644 (file)
 PROPNODECHAR   [a-zA-Z0-9,._+*#?@-]
 PATHCHAR       ({PROPNODECHAR}|[/])
 LABEL          [a-zA-Z_][a-zA-Z0-9_]*
+STRING         \"([^\\"]|\\.)*\"
+WS             [[:space:]]
+COMMENT                "/*"([^*]|\*+[^*/])*\*+"/"
+LINECOMMENT    "//".*\n
 
 %{
 #include "dtc.h"
@@ -52,29 +56,26 @@ static int dts_version; /* = 0 */
                                DPRINT("<V1>\n"); \
                                BEGIN(V1); \
                        }
+
+static void push_input_file(const char *filename);
+static int pop_input_file(void);
 %}
 
 %%
-<*>"/include/"         BEGIN(INCLUDE);
-
-<INCLUDE>\"[^"\n]*\"   {
-                       yytext[strlen(yytext) - 1] = 0;
-                       if (!push_input_file(yytext + 1)) {
-                               /* Some unrecoverable error.*/
-                               exit(1);
-                       }
-                       BEGIN_DEFAULT();
+<*>"/include/"{WS}*{STRING} {
+                       char *name = strchr(yytext, '\"') + 1;
+                       yytext[yyleng-1] = '\0';
+                       push_input_file(name);
                }
 
-
 <*><<EOF>>             {
                        if (!pop_input_file()) {
                                yyterminate();
                        }
                }
 
-<*>\"([^\\"]|\\.)*\"   {
-                       yylloc.filenum = srcpos_filenum;
+<*>{STRING}    {
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("String: %s\n", yytext);
                        yylval.data = data_copy_escape_string(yytext+1,
@@ -84,7 +85,7 @@ static int dts_version; /* = 0 */
                }
 
 <*>"/dts-v1/"  {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Keyword: /dts-v1/\n");
                        dts_version = 1;
@@ -93,7 +94,7 @@ static int dts_version; /* = 0 */
                }
 
 <*>"/memreserve/"      {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Keyword: /memreserve/\n");
                        BEGIN_DEFAULT();
@@ -101,7 +102,7 @@ static int dts_version; /* = 0 */
                }
 
 <*>{LABEL}:    {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Label: %s\n", yytext);
                        yylval.labelref = strdup(yytext);
@@ -110,7 +111,7 @@ static int dts_version; /* = 0 */
                }
 
 <INITIAL>[bodh]# {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        if (*yytext == 'b')
                                yylval.cbase = 2;
@@ -125,7 +126,7 @@ static int dts_version; /* = 0 */
                }
 
 <INITIAL>[0-9a-fA-F]+  {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yylval.literal = strdup(yytext);
                        DPRINT("Literal: '%s'\n", yylval.literal);
@@ -133,7 +134,7 @@ static int dts_version; /* = 0 */
                }
 
 <V1>[0-9]+|0[xX][0-9a-fA-F]+      {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yylval.literal = strdup(yytext);
                        DPRINT("Literal: '%s'\n", yylval.literal);
@@ -141,7 +142,7 @@ static int dts_version; /* = 0 */
                }
 
 \&{LABEL}      {       /* label reference */
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Ref: %s\n", yytext+1);
                        yylval.labelref = strdup(yytext+1);
@@ -149,7 +150,7 @@ static int dts_version; /* = 0 */
                }
 
 "&{/"{PATHCHAR}+\}     {       /* new-style path reference */
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yytext[yyleng-1] = '\0';
                        DPRINT("Ref: %s\n", yytext+2);
@@ -158,7 +159,7 @@ static int dts_version; /* = 0 */
                }
 
 <INITIAL>"&/"{PATHCHAR}+ {     /* old-style path reference */
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Ref: %s\n", yytext+1);
                        yylval.labelref = strdup(yytext+1);
@@ -166,7 +167,7 @@ static int dts_version; /* = 0 */
                }
 
 <BYTESTRING>[0-9a-fA-F]{2} {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yylval.byte = strtol(yytext, NULL, 16);
                        DPRINT("Byte: %02x\n", (int)yylval.byte);
@@ -174,7 +175,7 @@ static int dts_version; /* = 0 */
                }
 
 <BYTESTRING>"]"        {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("/BYTESTRING\n");
                        BEGIN_DEFAULT();
@@ -182,7 +183,7 @@ static int dts_version; /* = 0 */
                }
 
 <PROPNODENAME>{PROPNODECHAR}+ {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("PropNodeName: %s\n", yytext);
                        yylval.propnodename = strdup(yytext);
@@ -190,20 +191,19 @@ static int dts_version; /* = 0 */
                        return DT_PROPNODENAME;
                }
 
-
-<*>[[:space:]]+        /* eat whitespace */
-
-<*>"/*"([^*]|\*+[^*/])*\*+"/"  {
-                       yylloc.filenum = srcpos_filenum;
+"/incbin/"     {
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
-                       DPRINT("Comment: %s\n", yytext);
-                       /* eat comments */
+                       DPRINT("Binary Include\n");
+                       return DT_INCBIN;
                }
 
-<*>"//".*\n    /* eat line comments */
+<*>{WS}+       /* eat whitespace */
+<*>{COMMENT}+  /* eat C-style comments */
+<*>{LINECOMMENT}+ /* eat C++-style comments */
 
 <*>.           {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Char: %c (\\x%02x)\n", yytext[0],
                                (unsigned)yytext[0]);
@@ -227,14 +227,13 @@ static int dts_version; /* = 0 */
  */
 
 struct incl_file {
-       int filenum;
-       FILE *file;
+       struct dtc_file *file;
        YY_BUFFER_STATE yy_prev_buf;
        int yy_prev_lineno;
        struct incl_file *prev;
 };
 
-struct incl_file *incl_file_stack;
+static struct incl_file *incl_file_stack;
 
 
 /*
@@ -245,36 +244,34 @@ struct incl_file *incl_file_stack;
 static int incl_depth = 0;
 
 
-int push_input_file(const char *filename)
+static void push_input_file(const char *filename)
 {
-       FILE *f;
        struct incl_file *incl_file;
+       struct dtc_file *newfile;
+       struct search_path search, *searchptr = NULL;
 
-       if (!filename) {
-               yyerror("No include file name given.");
-               return 0;
-       }
+       assert(filename);
 
-       if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
-               yyerror("Includes nested too deeply");
-               return 0;
+       if (incl_depth++ >= MAX_INCLUDE_DEPTH)
+               die("Includes nested too deeply");
+
+       if (srcpos_file) {
+               search.dir = srcpos_file->dir;
+               search.next = NULL;
+               search.prev = NULL;
+               searchptr = &search;
        }
 
-       f = dtc_open_file(filename);
+       newfile = dtc_open_file(filename, searchptr);
 
-       incl_file = malloc(sizeof(struct incl_file));
-       if (!incl_file) {
-               yyerror("Can not allocate include file space.");
-               return 0;
-       }
+       incl_file = xmalloc(sizeof(struct incl_file));
 
        /*
         * Save current context.
         */
        incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
        incl_file->yy_prev_lineno = yylineno;
-       incl_file->filenum = srcpos_filenum;
-       incl_file->file = yyin;
+       incl_file->file = srcpos_file;
        incl_file->prev = incl_file_stack;
 
        incl_file_stack = incl_file;
@@ -282,23 +279,21 @@ int push_input_file(const char *filename)
        /*
         * Establish new context.
         */
-       srcpos_filenum = lookup_file_name(filename, 0);
+       srcpos_file = newfile;
        yylineno = 1;
-       yyin = f;
+       yyin = newfile->file;
        yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
-
-       return 1;
 }
 
 
-int pop_input_file(void)
+static int pop_input_file(void)
 {
        struct incl_file *incl_file;
 
        if (incl_file_stack == 0)
                return 0;
 
-       fclose(yyin);
+       dtc_close_file(srcpos_file);
 
        /*
         * Pop.
@@ -313,16 +308,13 @@ int pop_input_file(void)
        yy_delete_buffer(YY_CURRENT_BUFFER);
        yy_switch_to_buffer(incl_file->yy_prev_buf);
        yylineno = incl_file->yy_prev_lineno;
-       srcpos_filenum = incl_file->filenum;
-       yyin = incl_file->file;
+       srcpos_file = incl_file->file;
+       yyin = incl_file->file ? incl_file->file->file : NULL;
 
        /*
         * Free old state.
         */
        free(incl_file);
 
-       if (YY_CURRENT_BUFFER == 0)
-               return 0;
-
        return 1;
 }
index d0f742460f920ca503e938808d1dc129637a1ee6..ac392cb040f613bb62b508ea27e712283459c40f 100644 (file)
@@ -9,7 +9,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
+#define YY_FLEX_SUBMINOR_VERSION 34
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -31,7 +31,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 
 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
  * if you want the limit (max/min) macros for int types. 
@@ -94,11 +94,12 @@ typedef unsigned int flex_uint32_t;
 
 #else  /* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif /* __STDC__ */
+#endif /* defined (__STDC__) */
 #endif /* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -194,11 +195,13 @@ extern FILE *yyin, *yyout;
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
+ * Given that the standard has decreed that size_t exists since 1989,
+ * I guess we can afford to depend on it. Manoj.
  */
 
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
+typedef size_t yy_size_t;
 #endif
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -349,7 +352,7 @@ void yyfree (void *  );
 
 /* Begin user sect3 */
 
-#define yywrap() 1
+#define yywrap(n) 1
 #define YY_SKIP_YYWRAP
 
 typedef unsigned char YY_CHAR;
@@ -389,19 +392,20 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static yyconst flex_int16_t yy_accept[94] =
+static yyconst flex_int16_t yy_accept[104] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       21,   19,   16,   16,   19,   19,   19,    8,    8,   19,
-        8,   19,   19,   19,   19,   14,   15,   15,   19,    9,
-        9,   16,    0,    3,    0,    0,   10,    0,    0,    0,
-        0,    0,    0,    8,    8,    6,    0,    7,    0,    2,
-        0,   13,   13,   15,   15,    9,    0,   12,   10,    0,
-        0,    0,    0,   18,    0,    0,    0,    2,    9,    0,
-       17,    0,    0,    0,   11,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    4,    0,    0,    1,    0,    0,
-        0,    5,    0
-
+       21,   19,   16,   16,   19,   19,   19,    7,    7,   19,
+        7,   19,   19,   19,   19,   13,   14,   14,   19,    8,
+        8,   16,    0,    2,    0,    0,    9,    0,    0,    0,
+        0,    0,    0,    7,    7,    5,    0,    6,    0,   12,
+       12,   14,   14,    8,    0,   11,    9,    0,    0,    0,
+        0,   18,    0,    0,    0,    0,    8,    0,   17,    0,
+        0,    0,    0,    0,   10,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    3,   15,
+        0,    0,    0,    0,    0,    0,    0,    0,    1,    0,
+
+        0,    4,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -444,122 +448,126 @@ static yyconst flex_int32_t yy_meta[36] =
         7,    7,    7,    8,    1
     } ;
 
-static yyconst flex_int16_t yy_base[107] =
+static yyconst flex_int16_t yy_base[117] =
     {   0,
-        0,    0,   32,    0,   53,    0,   76,    0,  108,  111,
-      280,  288,   37,   39,   33,   36,  106,    0,  123,  146,
-      255,  251,   45,    0,  159,  288,    0,   53,  108,  172,
-      114,  127,  158,  288,  245,    0,    0,  234,  235,  236,
-      197,  195,  199,    0,    0,  288,    0,  288,  160,  288,
-      183,  288,    0,    0,  183,  182,    0,    0,    0,    0,
-      204,  189,  207,  288,  179,  187,  180,  194,    0,  171,
-      288,  196,  178,  174,  288,  169,  169,  177,  165,  153,
-      143,  155,  137,  118,  288,  122,   42,  288,   36,   36,
-       40,  288,  288,  212,  218,  223,  229,  234,  239,  245,
-
-      251,  255,  262,  270,  275,  280
+        0,    0,   30,    0,   44,    0,   67,    0,   97,  105,
+      302,  303,   35,   44,   40,   94,  112,    0,  129,  152,
+      296,  295,  159,    0,  176,  303,    0,  116,   95,  165,
+       49,   46,  102,  303,  296,    0,    0,  288,  290,  293,
+      264,  266,  270,    0,    0,  303,    0,  303,  264,  303,
+        0,    0,  195,  101,    0,    0,    0,    0,  284,  125,
+      277,  265,  225,  230,  216,  218,    0,  202,  224,  221,
+      217,  107,  196,  188,  303,  206,  179,  186,  178,  185,
+      183,  162,  161,  150,  169,  160,  145,  125,  303,  303,
+      137,  109,  190,  103,  203,  167,  108,  197,  303,  123,
+
+       29,  303,  303,  215,  221,  226,  229,  234,  240,  246,
+      250,  257,  265,  270,  275,  282
     } ;
 
-static yyconst flex_int16_t yy_def[107] =
+static yyconst flex_int16_t yy_def[117] =
     {   0,
-       93,    1,    1,    3,    3,    5,   93,    7,    3,    3,
-       93,   93,   93,   93,   94,   95,   93,   96,   93,   19,
-       19,   20,   97,   98,   20,   93,   99,  100,   95,   93,
-       93,   93,   94,   93,   94,  101,  102,   93,  103,  104,
-       93,   93,   93,   96,   19,   93,   20,   93,   97,   93,
-       97,   93,   20,   99,  100,   93,  105,  101,  102,  106,
-      103,  103,  104,   93,   93,   93,   93,   94,  105,  106,
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-       93,   93,    0,   93,   93,   93,   93,   93,   93,   93,
-
-       93,   93,   93,   93,   93,   93
+      103,    1,    1,    3,    3,    5,  103,    7,    3,    3,
+      103,  103,  103,  103,  104,  105,  103,  106,  103,   19,
+       19,   20,  103,  107,   20,  103,  108,  109,  105,  103,
+      103,  103,  104,  103,  104,  110,  111,  103,  112,  113,
+      103,  103,  103,  106,   19,  103,   20,  103,  103,  103,
+       20,  108,  109,  103,  114,  110,  111,  115,  112,  112,
+      113,  103,  103,  103,  103,  103,  114,  115,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  116,  103,  116,  103,  116,
+
+      103,  103,    0,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103
     } ;
 
-static yyconst flex_int16_t yy_nxt[324] =
+static yyconst flex_int16_t yy_nxt[339] =
     {   0,
        12,   13,   14,   15,   12,   16,   12,   12,   12,   17,
        18,   18,   18,   12,   19,   20,   20,   12,   12,   21,
        19,   21,   19,   22,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   12,   12,   23,   34,   12,   32,   32,
-       32,   32,   12,   12,   12,   36,   20,   33,   50,   92,
-       35,   20,   20,   20,   20,   20,   15,   54,   91,   54,
-       54,   54,   51,   24,   24,   24,   46,   25,   90,   38,
-       89,   26,   25,   25,   25,   25,   12,   13,   14,   15,
-       27,   12,   27,   27,   27,   17,   27,   27,   27,   12,
-       28,   28,   28,   12,   12,   28,   28,   28,   28,   28,
-
-       28,   28,   28,   28,   28,   28,   28,   28,   28,   12,
-       12,   15,   39,   29,   15,   40,   29,   93,   30,   31,
-       31,   30,   31,   31,   56,   56,   56,   41,   32,   32,
-       42,   88,   43,   45,   45,   45,   46,   45,   47,   47,
-       87,   38,   45,   45,   45,   45,   47,   47,   47,   47,
-       47,   47,   47,   47,   47,   47,   47,   47,   47,   86,
-       47,   34,   33,   50,   85,   47,   47,   47,   47,   53,
-       53,   53,   84,   53,   83,   35,   82,   51,   53,   53,
-       53,   53,   56,   56,   56,   93,   68,   54,   57,   54,
-       54,   54,   56,   56,   56,   62,   46,   34,   71,   81,
-
-       80,   79,   78,   77,   76,   75,   74,   73,   72,   64,
-       62,   35,   33,   33,   33,   33,   33,   33,   33,   33,
-       37,   67,   66,   37,   37,   37,   44,   65,   44,   49,
-       49,   49,   49,   49,   49,   49,   49,   52,   64,   52,
-       54,   62,   54,   60,   54,   54,   55,   93,   55,   55,
-       55,   55,   58,   58,   58,   48,   58,   58,   59,   48,
-       59,   59,   61,   61,   61,   61,   61,   61,   61,   61,
-       63,   63,   63,   63,   63,   63,   63,   63,   69,   93,
-       69,   70,   70,   70,   93,   70,   70,   11,   93,   93,
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-       93,   93,   93
+       20,   20,   20,   12,   12,   12,   32,   32,  102,   23,
+       12,   12,   12,   34,   20,   32,   32,   32,   32,   20,
+       20,   20,   20,   20,   24,   24,   24,   35,   25,   54,
+       54,   54,   26,   25,   25,   25,   25,   12,   13,   14,
+       15,   27,   12,   27,   27,   27,   23,   27,   27,   27,
+       12,   28,   28,   28,   12,   12,   28,   28,   28,   28,
+       28,   28,   28,   28,   28,   28,   28,   28,   28,   28,
+
+       12,   12,   29,   36,  103,   34,   17,   30,   31,   31,
+       29,   54,   54,   54,   17,   30,   31,   31,   39,   35,
+       52,   40,   52,   52,   52,  103,   78,   38,   38,   46,
+      101,   60,   79,   41,   69,   97,   42,   94,   43,   45,
+       45,   45,   46,   45,   47,   47,   93,   92,   45,   45,
+       45,   45,   47,   47,   47,   47,   47,   47,   47,   47,
+       47,   47,   47,   47,   47,   39,   47,   91,   40,   90,
+       99,   47,   47,   47,   47,   54,   54,   54,   89,   88,
+       41,   55,   87,   49,  100,   43,   51,   51,   51,   86,
+       51,   95,   95,   96,   85,   51,   51,   51,   51,   52,
+
+       99,   52,   52,   52,   95,   95,   96,   84,   46,   83,
+       82,   81,   39,   79,  100,   33,   33,   33,   33,   33,
+       33,   33,   33,   37,   80,   77,   37,   37,   37,   44,
+       40,   44,   50,   76,   50,   52,   75,   52,   74,   52,
+       52,   53,   73,   53,   53,   53,   53,   56,   56,   56,
+       72,   56,   56,   57,   71,   57,   57,   59,   59,   59,
+       59,   59,   59,   59,   59,   61,   61,   61,   61,   61,
+       61,   61,   61,   67,   70,   67,   68,   68,   68,   62,
+       68,   68,   98,   98,   98,   98,   98,   98,   98,   98,
+       60,   66,   65,   64,   63,   62,   60,   58,  103,   48,
+
+       48,  103,   11,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103
     } ;
 
-static yyconst flex_int16_t yy_chk[324] =
+static yyconst flex_int16_t yy_chk[339] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    3,   15,    3,   13,   13,
-       14,   14,    3,    3,    3,   16,    3,   23,   23,   91,
-       15,    3,    3,    3,    3,    3,    5,   28,   90,   28,
-       28,   28,   23,    5,    5,    5,   28,    5,   89,   16,
-       87,    5,    5,    5,    5,    5,    7,    7,    7,    7,
+        1,    1,    1,    1,    1,    3,   13,   13,  101,    3,
+        3,    3,    3,   15,    3,   14,   14,   32,   32,    3,
+        3,    3,    3,    3,    5,    5,    5,   15,    5,   31,
+       31,   31,    5,    5,    5,    5,    5,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    9,   17,    9,   10,   17,   10,   29,    9,    9,
-        9,   10,   10,   10,   31,   31,   31,   17,   32,   32,
-       17,   86,   17,   19,   19,   19,   19,   19,   19,   19,
-       84,   29,   19,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   20,   20,   20,   83,
-       20,   33,   49,   49,   82,   20,   20,   20,   20,   25,
-       25,   25,   81,   25,   80,   33,   79,   49,   25,   25,
-       25,   25,   30,   30,   30,   51,   51,   55,   30,   55,
-       55,   55,   56,   56,   56,   62,   55,   68,   62,   78,
-
-       77,   76,   74,   73,   72,   70,   67,   66,   65,   63,
-       61,   68,   94,   94,   94,   94,   94,   94,   94,   94,
-       95,   43,   42,   95,   95,   95,   96,   41,   96,   97,
-       97,   97,   97,   97,   97,   97,   97,   98,   40,   98,
-       99,   39,   99,   38,   99,   99,  100,   35,  100,  100,
-      100,  100,  101,  101,  101,   22,  101,  101,  102,   21,
-      102,  102,  103,  103,  103,  103,  103,  103,  103,  103,
-      104,  104,  104,  104,  104,  104,  104,  104,  105,   11,
-      105,  106,  106,  106,    0,  106,  106,   93,   93,   93,
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
-       93,   93,   93
+
+        7,    7,    9,   16,   29,   33,    9,    9,    9,    9,
+       10,   54,   54,   54,   10,   10,   10,   10,   17,   33,
+       28,   17,   28,   28,   28,  100,   72,   16,   29,   28,
+       97,   60,   72,   17,   60,   94,   17,   92,   17,   19,
+       19,   19,   19,   19,   19,   19,   91,   88,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   20,   20,   20,   23,   20,   87,   23,   86,
+       96,   20,   20,   20,   20,   30,   30,   30,   85,   84,
+       23,   30,   83,   23,   96,   23,   25,   25,   25,   82,
+       25,   93,   93,   93,   81,   25,   25,   25,   25,   53,
+
+       98,   53,   53,   53,   95,   95,   95,   80,   53,   79,
+       78,   77,   76,   74,   98,  104,  104,  104,  104,  104,
+      104,  104,  104,  105,   73,   71,  105,  105,  105,  106,
+       70,  106,  107,   69,  107,  108,   68,  108,   66,  108,
+      108,  109,   65,  109,  109,  109,  109,  110,  110,  110,
+       64,  110,  110,  111,   63,  111,  111,  112,  112,  112,
+      112,  112,  112,  112,  112,  113,  113,  113,  113,  113,
+      113,  113,  113,  114,   62,  114,  115,  115,  115,   61,
+      115,  115,  116,  116,  116,  116,  116,  116,  116,  116,
+       59,   49,   43,   42,   41,   40,   39,   38,   35,   22,
+
+       21,   11,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
+      103,  103,  103,  103,  103,  103,  103,  103
     } ;
 
 /* Table of booleans, true if rule could match eol. */
 static yyconst flex_int32_t yy_rule_can_match_eol[21] =
     {   0,
-0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 
+1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 
     0,     };
 
 static yy_state_type yy_last_accepting_state;
@@ -600,7 +608,7 @@ char *yytext;
 
 
 
-#line 33 "dtc-lexer.l"
+#line 37 "dtc-lexer.l"
 #include "dtc.h"
 #include "srcpos.h"
 #include "dtc-parser.tab.h"
@@ -623,7 +631,10 @@ static int dts_version; /* = 0 */
                                DPRINT("<V1>\n"); \
                                BEGIN(V1); \
                        }
-#line 627 "dtc-lexer.lex.c"
+
+static void push_input_file(const char *filename);
+static int pop_input_file(void);
+#line 638 "dtc-lexer.lex.c"
 
 #define INITIAL 0
 #define INCLUDE 1
@@ -685,7 +696,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -696,7 +707,7 @@ static int input (void );
        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
                { \
                int c = '*'; \
-               size_t n; \
+               int n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -778,9 +789,9 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
     
-#line 57 "dtc-lexer.l"
+#line 64 "dtc-lexer.l"
 
-#line 784 "dtc-lexer.lex.c"
+#line 795 "dtc-lexer.lex.c"
 
        if ( !(yy_init) )
                {
@@ -833,13 +844,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 94 )
+                               if ( yy_current_state >= 104 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 288 );
+               while ( yy_base[yy_current_state] != 303 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -874,20 +885,13 @@ do_action:        /* This label is used only to access EOF actions. */
                        goto yy_find_action;
 
 case 1:
+/* rule 1 can match eol */
 YY_RULE_SETUP
-#line 58 "dtc-lexer.l"
-BEGIN(INCLUDE);
-       YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 60 "dtc-lexer.l"
+#line 65 "dtc-lexer.l"
 {
-                       yytext[strlen(yytext) - 1] = 0;
-                       if (!push_input_file(yytext + 1)) {
-                               /* Some unrecoverable error.*/
-                               exit(1);
-                       }
-                       BEGIN_DEFAULT();
+                       char *name = strchr(yytext, '\"') + 1;
+                       yytext[yyleng-1] = '\0';
+                       push_input_file(name);
                }
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
@@ -895,19 +899,19 @@ case YY_STATE_EOF(INCLUDE):
 case YY_STATE_EOF(BYTESTRING):
 case YY_STATE_EOF(PROPNODENAME):
 case YY_STATE_EOF(V1):
-#line 70 "dtc-lexer.l"
+#line 71 "dtc-lexer.l"
 {
                        if (!pop_input_file()) {
                                yyterminate();
                        }
                }
        YY_BREAK
-case 3:
-/* rule 3 can match eol */
+case 2:
+/* rule 2 can match eol */
 YY_RULE_SETUP
-#line 76 "dtc-lexer.l"
+#line 77 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("String: %s\n", yytext);
                        yylval.data = data_copy_escape_string(yytext+1,
@@ -916,11 +920,11 @@ YY_RULE_SETUP
                        return DT_STRING;
                }
        YY_BREAK
-case 4:
+case 3:
 YY_RULE_SETUP
-#line 86 "dtc-lexer.l"
+#line 87 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Keyword: /dts-v1/\n");
                        dts_version = 1;
@@ -928,22 +932,22 @@ YY_RULE_SETUP
                        return DT_V1;
                }
        YY_BREAK
-case 5:
+case 4:
 YY_RULE_SETUP
-#line 95 "dtc-lexer.l"
+#line 96 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Keyword: /memreserve/\n");
                        BEGIN_DEFAULT();
                        return DT_MEMRESERVE;
                }
        YY_BREAK
-case 6:
+case 5:
 YY_RULE_SETUP
-#line 103 "dtc-lexer.l"
+#line 104 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Label: %s\n", yytext);
                        yylval.labelref = strdup(yytext);
@@ -951,11 +955,11 @@ YY_RULE_SETUP
                        return DT_LABEL;
                }
        YY_BREAK
-case 7:
+case 6:
 YY_RULE_SETUP
-#line 112 "dtc-lexer.l"
+#line 113 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        if (*yytext == 'b')
                                yylval.cbase = 2;
@@ -969,44 +973,44 @@ YY_RULE_SETUP
                        return DT_BASE;
                }
        YY_BREAK
-case 8:
+case 7:
 YY_RULE_SETUP
-#line 127 "dtc-lexer.l"
+#line 128 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yylval.literal = strdup(yytext);
                        DPRINT("Literal: '%s'\n", yylval.literal);
                        return DT_LEGACYLITERAL;
                }
        YY_BREAK
-case 9:
+case 8:
 YY_RULE_SETUP
-#line 135 "dtc-lexer.l"
+#line 136 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yylval.literal = strdup(yytext);
                        DPRINT("Literal: '%s'\n", yylval.literal);
                        return DT_LITERAL;
                }
        YY_BREAK
-case 10:
+case 9:
 YY_RULE_SETUP
-#line 143 "dtc-lexer.l"
+#line 144 "dtc-lexer.l"
 {      /* label reference */
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Ref: %s\n", yytext+1);
                        yylval.labelref = strdup(yytext+1);
                        return DT_REF;
                }
        YY_BREAK
-case 11:
+case 10:
 YY_RULE_SETUP
-#line 151 "dtc-lexer.l"
+#line 152 "dtc-lexer.l"
 {      /* new-style path reference */
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yytext[yyleng-1] = '\0';
                        DPRINT("Ref: %s\n", yytext+2);
@@ -1014,44 +1018,44 @@ YY_RULE_SETUP
                        return DT_REF;
                }
        YY_BREAK
-case 12:
+case 11:
 YY_RULE_SETUP
-#line 160 "dtc-lexer.l"
+#line 161 "dtc-lexer.l"
 {      /* old-style path reference */
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Ref: %s\n", yytext+1);
                        yylval.labelref = strdup(yytext+1);
                        return DT_REF;
                }
        YY_BREAK
-case 13:
+case 12:
 YY_RULE_SETUP
-#line 168 "dtc-lexer.l"
+#line 169 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        yylval.byte = strtol(yytext, NULL, 16);
                        DPRINT("Byte: %02x\n", (int)yylval.byte);
                        return DT_BYTE;
                }
        YY_BREAK
-case 14:
+case 13:
 YY_RULE_SETUP
-#line 176 "dtc-lexer.l"
+#line 177 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("/BYTESTRING\n");
                        BEGIN_DEFAULT();
                        return ']';
                }
        YY_BREAK
-case 15:
+case 14:
 YY_RULE_SETUP
-#line 184 "dtc-lexer.l"
+#line 185 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("PropNodeName: %s\n", yytext);
                        yylval.propnodename = strdup(yytext);
@@ -1059,34 +1063,39 @@ YY_RULE_SETUP
                        return DT_PROPNODENAME;
                }
        YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 194 "dtc-lexer.l"
+{
+                       yylloc.file = srcpos_file;
+                       yylloc.first_line = yylineno;
+                       DPRINT("Binary Include\n");
+                       return DT_INCBIN;
+               }
+       YY_BREAK
 case 16:
 /* rule 16 can match eol */
 YY_RULE_SETUP
-#line 194 "dtc-lexer.l"
+#line 201 "dtc-lexer.l"
 /* eat whitespace */
        YY_BREAK
 case 17:
 /* rule 17 can match eol */
 YY_RULE_SETUP
-#line 196 "dtc-lexer.l"
-{
-                       yylloc.filenum = srcpos_filenum;
-                       yylloc.first_line = yylineno;
-                       DPRINT("Comment: %s\n", yytext);
-                       /* eat comments */
-               }
+#line 202 "dtc-lexer.l"
+/* eat C-style comments */
        YY_BREAK
 case 18:
 /* rule 18 can match eol */
 YY_RULE_SETUP
 #line 203 "dtc-lexer.l"
-/* eat line comments */
+/* eat C++-style comments */
        YY_BREAK
 case 19:
 YY_RULE_SETUP
 #line 205 "dtc-lexer.l"
 {
-                       yylloc.filenum = srcpos_filenum;
+                       yylloc.file = srcpos_file;
                        yylloc.first_line = yylineno;
                        DPRINT("Char: %c (\\x%02x)\n", yytext[0],
                                (unsigned)yytext[0]);
@@ -1107,7 +1116,7 @@ YY_RULE_SETUP
 #line 222 "dtc-lexer.l"
 ECHO;
        YY_BREAK
-#line 1111 "dtc-lexer.lex.c"
+#line 1120 "dtc-lexer.lex.c"
 
        case YY_END_OF_BUFFER:
                {
@@ -1360,6 +1369,14 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
+       if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
        (yy_n_chars) += number_to_move;
        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -1389,7 +1406,7 @@ static int yy_get_next_buffer (void)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 94 )
+                       if ( yy_current_state >= 104 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1417,11 +1434,11 @@ static int yy_get_next_buffer (void)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 94 )
+               if ( yy_current_state >= 104 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 93);
+       yy_is_jam = (yy_current_state == 103);
 
        return yy_is_jam ? 0 : yy_current_state;
 }
@@ -1743,7 +1760,9 @@ static void yyensure_buffer_stack (void)
                (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
                                                                (num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                );
-               
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
                memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
                                
                (yy_buffer_stack_max) = num_to_alloc;
@@ -1761,6 +1780,8 @@ static void yyensure_buffer_stack (void)
                                                                ((yy_buffer_stack),
                                                                num_to_alloc * sizeof(struct yy_buffer_state*)
                                                                );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 
                /* zero only the new slots.*/
                memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -2072,14 +2093,13 @@ void yyfree (void * ptr )
  */
 
 struct incl_file {
-       int filenum;
-       FILE *file;
+       struct dtc_file *file;
        YY_BUFFER_STATE yy_prev_buf;
        int yy_prev_lineno;
        struct incl_file *prev;
 };
 
-struct incl_file *incl_file_stack;
+static struct incl_file *incl_file_stack;
 
 
 /*
@@ -2090,36 +2110,34 @@ struct incl_file *incl_file_stack;
 static int incl_depth = 0;
 
 
-int push_input_file(const char *filename)
+static void push_input_file(const char *filename)
 {
-       FILE *f;
        struct incl_file *incl_file;
+       struct dtc_file *newfile;
+       struct search_path search, *searchptr = NULL;
 
-       if (!filename) {
-               yyerror("No include file name given.");
-               return 0;
-       }
+       assert(filename);
 
-       if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
-               yyerror("Includes nested too deeply");
-               return 0;
+       if (incl_depth++ >= MAX_INCLUDE_DEPTH)
+               die("Includes nested too deeply");
+
+       if (srcpos_file) {
+               search.dir = srcpos_file->dir;
+               search.next = NULL;
+               search.prev = NULL;
+               searchptr = &search;
        }
 
-       f = dtc_open_file(filename);
+       newfile = dtc_open_file(filename, searchptr);
 
-       incl_file = malloc(sizeof(struct incl_file));
-       if (!incl_file) {
-               yyerror("Can not allocate include file space.");
-               return 0;
-       }
+       incl_file = xmalloc(sizeof(struct incl_file));
 
        /*
         * Save current context.
         */
        incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
        incl_file->yy_prev_lineno = yylineno;
-       incl_file->filenum = srcpos_filenum;
-       incl_file->file = yyin;
+       incl_file->file = srcpos_file;
        incl_file->prev = incl_file_stack;
 
        incl_file_stack = incl_file;
@@ -2127,23 +2145,21 @@ int push_input_file(const char *filename)
        /*
         * Establish new context.
         */
-       srcpos_filenum = lookup_file_name(filename, 0);
+       srcpos_file = newfile;
        yylineno = 1;
-       yyin = f;
+       yyin = newfile->file;
        yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
-
-       return 1;
 }
 
 
-int pop_input_file(void)
+static int pop_input_file(void)
 {
        struct incl_file *incl_file;
 
        if (incl_file_stack == 0)
                return 0;
 
-       fclose(yyin);
+       dtc_close_file(srcpos_file);
 
        /*
         * Pop.
@@ -2158,17 +2174,14 @@ int pop_input_file(void)
        yy_delete_buffer(YY_CURRENT_BUFFER);
        yy_switch_to_buffer(incl_file->yy_prev_buf);
        yylineno = incl_file->yy_prev_lineno;
-       srcpos_filenum = incl_file->filenum;
-       yyin = incl_file->file;
+       srcpos_file = incl_file->file;
+       yyin = incl_file->file ? incl_file->file->file : NULL;
 
        /*
         * Free old state.
         */
        free(incl_file);
 
-       if (YY_CURRENT_BUFFER == 0)
-               return 0;
-
        return 1;
 }
 
index 28e6ec0296a1598cea08fba484fbbc022158f6ad..27129377e5d217dce3ca2a4501f9c36a6b181071 100644 (file)
@@ -75,7 +75,8 @@
      DT_BYTE = 264,
      DT_STRING = 265,
      DT_LABEL = 266,
-     DT_REF = 267
+     DT_REF = 267,
+     DT_INCBIN = 268
    };
 #endif
 /* Tokens.  */
@@ -89,6 +90,7 @@
 #define DT_STRING 265
 #define DT_LABEL 266
 #define DT_REF 267
+#define DT_INCBIN 268
 
 
 
 /* Copy the first part of user declarations.  */
 #line 23 "dtc-parser.y"
 
+#include <stdio.h>
+
 #include "dtc.h"
 #include "srcpos.h"
 
-int yylex(void);
-unsigned long long eval_literal(const char *s, int base, int bits);
+extern int yylex(void);
 
 extern struct boot_info *the_boot_info;
+extern int treesource_error;
 
+static unsigned long long eval_literal(const char *s, int base, int bits);
 
 
 /* Enabling traces.  */
@@ -126,16 +131,16 @@ extern struct boot_info *the_boot_info;
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 34 "dtc-parser.y"
+#line 37 "dtc-parser.y"
 {
        char *propnodename;
        char *literal;
        char *labelref;
        unsigned int cbase;
-       u8 byte;
+       uint8_t byte;
        struct data data;
 
-       u64 addr;
+       uint64_t addr;
        cell_t cell;
        struct property *prop;
        struct property *proplist;
@@ -144,7 +149,7 @@ typedef union YYSTYPE
        struct reserve_info *re;
 }
 /* Line 187 of yacc.c.  */
-#line 148 "dtc-parser.tab.c"
+#line 153 "dtc-parser.tab.c"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -169,7 +174,7 @@ typedef struct YYLTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 173 "dtc-parser.tab.c"
+#line 178 "dtc-parser.tab.c"
 
 #ifdef short
 # undef short
@@ -386,20 +391,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  9
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   60
+#define YYLAST   73
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  24
+#define YYNTOKENS  27
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  20
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  43
+#define YYNRULES  45
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  67
+#define YYNSTATES  76
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   267
+#define YYMAXUTOK   268
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -411,15 +416,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    23,    14,     2,    15,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    13,
-      19,    18,    20,     2,     2,     2,     2,     2,     2,     2,
+      24,    26,     2,     2,    25,    15,     2,    16,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    14,
+      20,    19,    21,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    21,     2,    22,     2,     2,     2,     2,     2,     2,
+       2,    22,     2,    23,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    16,     2,    17,     2,     2,     2,     2,
+       2,     2,     2,    17,     2,    18,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -433,7 +438,7 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12
+       5,     6,     7,     8,     9,    10,    11,    12,    13
 };
 
 #if YYDEBUG
@@ -443,37 +448,39 @@ static const yytype_uint8 yyprhs[] =
 {
        0,     0,     3,     8,    11,    12,    15,    21,    22,    25,
       27,    34,    36,    38,    41,    47,    48,    51,    57,    61,
-      64,    69,    74,    77,    80,    81,    84,    87,    88,    91,
-      94,    97,    98,   100,   102,   105,   106,   109,   112,   113,
-     116,   119,   123,   124
+      64,    69,    74,    77,    87,    93,    96,    97,   100,   103,
+     104,   107,   110,   113,   114,   116,   118,   121,   122,   125,
+     128,   129,   132,   135,   139,   140
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      25,     0,    -1,     3,    13,    26,    31,    -1,    28,    31,
-      -1,    -1,    27,    26,    -1,    43,     4,    30,    30,    13,
-      -1,    -1,    29,    28,    -1,    27,    -1,    43,     4,    30,
-      14,    30,    13,    -1,     6,    -1,     7,    -1,    15,    32,
-      -1,    16,    33,    41,    17,    13,    -1,    -1,    33,    34,
-      -1,    43,     5,    18,    35,    13,    -1,    43,     5,    13,
-      -1,    36,    10,    -1,    36,    19,    37,    20,    -1,    36,
-      21,    40,    22,    -1,    36,    12,    -1,    35,    11,    -1,
-      -1,    35,    23,    -1,    36,    11,    -1,    -1,    37,    39,
-      -1,    37,    12,    -1,    37,    11,    -1,    -1,     8,    -1,
-       6,    -1,    38,     7,    -1,    -1,    40,     9,    -1,    40,
-      11,    -1,    -1,    42,    41,    -1,    42,    34,    -1,    43,
-       5,    32,    -1,    -1,    11,    -1
+      28,     0,    -1,     3,    14,    29,    34,    -1,    31,    34,
+      -1,    -1,    30,    29,    -1,    46,     4,    33,    33,    14,
+      -1,    -1,    32,    31,    -1,    30,    -1,    46,     4,    33,
+      15,    33,    14,    -1,     6,    -1,     7,    -1,    16,    35,
+      -1,    17,    36,    44,    18,    14,    -1,    -1,    36,    37,
+      -1,    46,     5,    19,    38,    14,    -1,    46,     5,    14,
+      -1,    39,    10,    -1,    39,    20,    40,    21,    -1,    39,
+      22,    43,    23,    -1,    39,    12,    -1,    39,    13,    24,
+      10,    25,    33,    25,    33,    26,    -1,    39,    13,    24,
+      10,    26,    -1,    38,    11,    -1,    -1,    38,    25,    -1,
+      39,    11,    -1,    -1,    40,    42,    -1,    40,    12,    -1,
+      40,    11,    -1,    -1,     8,    -1,     6,    -1,    41,     7,
+      -1,    -1,    43,     9,    -1,    43,    11,    -1,    -1,    45,
+      44,    -1,    45,    37,    -1,    46,     5,    35,    -1,    -1,
+      11,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,    85,    85,    89,    97,   100,   107,   115,   118,   125,
-     129,   136,   140,   147,   154,   162,   165,   172,   176,   183,
-     187,   191,   195,   199,   207,   210,   214,   222,   225,   229,
-     234,   242,   245,   249,   253,   261,   264,   268,   276,   279,
-     283,   291,   299,   302
+       0,    89,    89,    93,   101,   104,   111,   119,   122,   129,
+     133,   140,   144,   151,   158,   166,   169,   176,   180,   187,
+     191,   195,   199,   203,   220,   231,   239,   242,   246,   254,
+     257,   261,   266,   274,   277,   281,   285,   293,   296,   300,
+     308,   311,   315,   323,   331,   334
 };
 #endif
 
@@ -484,12 +491,12 @@ static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
   "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
-  "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'",
-  "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile",
-  "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr",
-  "devicetree", "nodedef", "proplist", "propdef", "propdata",
-  "propdataprefix", "celllist", "cellbase", "cellval", "bytestring",
-  "subnodes", "subnode", "label", 0
+  "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'",
+  "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','",
+  "')'", "$accept", "sourcefile", "memreserves", "memreserve",
+  "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef",
+  "proplist", "propdef", "propdata", "propdataprefix", "celllist",
+  "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0
 };
 #endif
 
@@ -499,19 +506,19 @@ static const char *const yytname[] =
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,    59,    45,    47,   123,   125,    61,    60,
-      62,    91,    93,    44
+     265,   266,   267,   268,    59,    45,    47,   123,   125,    61,
+      60,    62,    91,    93,    40,    44,    41
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    24,    25,    25,    26,    26,    27,    28,    28,    29,
-      29,    30,    30,    31,    32,    33,    33,    34,    34,    35,
-      35,    35,    35,    35,    36,    36,    36,    37,    37,    37,
-      37,    38,    38,    39,    39,    40,    40,    40,    41,    41,
-      41,    42,    43,    43
+       0,    27,    28,    28,    29,    29,    30,    31,    31,    32,
+      32,    33,    33,    34,    35,    36,    36,    37,    37,    38,
+      38,    38,    38,    38,    38,    38,    39,    39,    39,    40,
+      40,    40,    40,    41,    41,    42,    42,    43,    43,    43,
+      44,    44,    44,    45,    46,    46
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -519,9 +526,9 @@ static const yytype_uint8 yyr2[] =
 {
        0,     2,     4,     2,     0,     2,     5,     0,     2,     1,
        6,     1,     1,     2,     5,     0,     2,     5,     3,     2,
-       4,     4,     2,     2,     0,     2,     2,     0,     2,     2,
-       2,     0,     1,     1,     2,     0,     2,     2,     0,     2,
-       2,     3,     0,     1
+       4,     4,     2,     9,     5,     2,     0,     2,     2,     0,
+       2,     2,     2,     0,     1,     1,     2,     0,     2,     2,
+       0,     2,     2,     3,     0,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -529,81 +536,86 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       7,     0,    43,     0,     9,     0,     7,     0,     4,     1,
+       7,     0,    45,     0,     9,     0,     7,     0,     4,     1,
        0,     3,     8,     0,     0,     4,     0,    15,    13,    11,
-      12,     0,     2,     5,     0,    38,     0,     0,     0,    16,
-       0,    38,     0,     0,     6,     0,    40,    39,     0,    10,
-      14,    18,    24,    41,     0,     0,    23,    17,    25,    19,
-      26,    22,    27,    35,    31,     0,    33,    32,    30,    29,
-      20,     0,    28,    36,    37,    21,    34
+      12,     0,     2,     5,     0,    40,     0,     0,     0,    16,
+       0,    40,     0,     0,     6,     0,    42,    41,     0,    10,
+      14,    18,    26,    43,     0,     0,    25,    17,    27,    19,
+      28,    22,     0,    29,    37,     0,    33,     0,     0,    35,
+      34,    32,    31,    20,     0,    30,    38,    39,    21,     0,
+      24,    36,     0,     0,     0,    23
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
       -1,     3,    14,     4,     5,     6,    27,    11,    18,    25,
-      29,    44,    45,    54,    61,    62,    55,    30,    31,     7
+      29,    44,    45,    56,    64,    65,    57,    30,    31,     7
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -13
+#define YYPACT_NINF -14
 static const yytype_int8 yypact[] =
 {
-      23,    11,   -13,    37,   -13,    -4,    18,    39,    18,   -13,
-      28,   -13,   -13,    34,    -4,    18,    41,   -13,   -13,   -13,
-     -13,    25,   -13,   -13,    34,    -3,    34,    33,    34,   -13,
-      30,    -3,    43,    36,   -13,    38,   -13,   -13,    20,   -13,
-     -13,   -13,   -13,   -13,     2,     9,   -13,   -13,   -13,   -13,
-     -13,   -13,   -13,   -13,    -2,    -6,   -13,   -13,   -13,   -13,
-     -13,    45,   -13,   -13,   -13,   -13,   -13
+      30,   -11,   -14,     7,   -14,    -1,    27,    13,    27,   -14,
+       8,   -14,   -14,    40,    -1,    27,    35,   -14,   -14,   -14,
+     -14,    21,   -14,   -14,    40,    24,    40,    28,    40,   -14,
+      32,    24,    46,    38,   -14,    39,   -14,   -14,    26,   -14,
+     -14,   -14,   -14,   -14,    -9,    10,   -14,   -14,   -14,   -14,
+     -14,   -14,    31,   -14,   -14,    44,    -2,     3,    23,   -14,
+     -14,   -14,   -14,   -14,    50,   -14,   -14,   -14,   -14,    40,
+     -14,   -14,    33,    40,    36,   -14
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -13,   -13,    35,    27,    47,   -13,   -12,    40,    17,   -13,
-      26,   -13,   -13,   -13,   -13,   -13,   -13,    29,   -13,    -8
+     -14,   -14,    48,    29,    53,   -14,   -13,    47,    34,   -14,
+      37,   -14,   -14,   -14,   -14,   -14,   -14,    42,   -14,    -7
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -43
+#define YYTABLE_NINF -45
 static const yytype_int8 yytable[] =
 {
-      16,    21,   -42,    63,    56,    64,    57,    16,     2,    58,
-      59,    10,    28,    46,    33,    47,    65,    32,    60,    49,
-      50,    51,   -42,    32,     8,    48,     1,   -42,    52,     2,
-      53,    19,    20,    41,     2,    15,    17,     9,    42,    26,
-      19,    20,    15,    13,    17,    24,    34,    35,    38,    39,
-      23,    40,    66,    12,    22,    43,     0,    36,     0,     0,
-      37
+      21,    16,    46,     8,    59,    47,    60,     9,    16,    61,
+      62,    28,    66,    33,    67,    10,    48,    13,    32,    63,
+      49,    50,    51,    52,    32,    17,    68,    19,    20,   -44,
+      53,   -44,    54,     1,   -44,     2,    26,    15,     2,    24,
+      41,     2,    34,    17,    15,    42,    19,    20,    69,    70,
+      35,    38,    39,    40,    58,    55,    72,    71,    73,    12,
+      74,    22,    75,    23,     0,     0,     0,     0,    36,     0,
+       0,     0,    43,    37
 };
 
 static const yytype_int8 yycheck[] =
 {
-       8,    13,     5,     9,     6,    11,     8,    15,    11,    11,
-      12,    15,    24,    11,    26,    13,    22,    25,    20,    10,
-      11,    12,     4,    31,    13,    23,     3,     4,    19,    11,
-      21,     6,     7,    13,    11,     8,    16,     0,    18,    14,
-       6,     7,    15,     4,    16,     4,    13,    17,     5,    13,
-      15,    13,     7,     6,    14,    38,    -1,    31,    -1,    -1,
-      31
+      13,     8,    11,    14,     6,    14,     8,     0,    15,    11,
+      12,    24,     9,    26,    11,    16,    25,     4,    25,    21,
+      10,    11,    12,    13,    31,    17,    23,     6,     7,     5,
+      20,     4,    22,     3,     4,    11,    15,     8,    11,     4,
+      14,    11,    14,    17,    15,    19,     6,     7,    25,    26,
+      18,     5,    14,    14,    10,    24,    69,     7,    25,     6,
+      73,    14,    26,    15,    -1,    -1,    -1,    -1,    31,    -1,
+      -1,    -1,    38,    31
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,    11,    25,    27,    28,    29,    43,    13,     0,
-      15,    31,    28,     4,    26,    27,    43,    16,    32,     6,
-       7,    30,    31,    26,     4,    33,    14,    30,    30,    34,
-      41,    42,    43,    30,    13,    17,    34,    41,     5,    13,
-      13,    13,    18,    32,    35,    36,    11,    13,    23,    10,
-      11,    12,    19,    21,    37,    40,     6,     8,    11,    12,
-      20,    38,    39,     9,    11,    22,     7
+       0,     3,    11,    28,    30,    31,    32,    46,    14,     0,
+      16,    34,    31,     4,    29,    30,    46,    17,    35,     6,
+       7,    33,    34,    29,     4,    36,    15,    33,    33,    37,
+      44,    45,    46,    33,    14,    18,    37,    44,     5,    14,
+      14,    14,    19,    35,    38,    39,    11,    14,    25,    10,
+      11,    12,    13,    20,    22,    24,    40,    43,    10,     6,
+       8,    11,    12,    21,    41,    42,     9,    11,    23,    25,
+      26,     7,    33,    25,    33,    26
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1440,289 +1452,323 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 86 "dtc-parser.y"
+#line 90 "dtc-parser.y"
     {
-                       the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node));
+                       the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0);
                ;}
     break;
 
   case 3:
-#line 90 "dtc-parser.y"
+#line 94 "dtc-parser.y"
     {
-                       the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node));
+                       the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0);
                ;}
     break;
 
   case 4:
-#line 97 "dtc-parser.y"
+#line 101 "dtc-parser.y"
     {
                        (yyval.re) = NULL;
                ;}
     break;
 
   case 5:
-#line 101 "dtc-parser.y"
+#line 105 "dtc-parser.y"
     {
                        (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
                ;}
     break;
 
   case 6:
-#line 108 "dtc-parser.y"
+#line 112 "dtc-parser.y"
     {
                        (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
                ;}
     break;
 
   case 7:
-#line 115 "dtc-parser.y"
+#line 119 "dtc-parser.y"
     {
                        (yyval.re) = NULL;
                ;}
     break;
 
   case 8:
-#line 119 "dtc-parser.y"
+#line 123 "dtc-parser.y"
     {
                        (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
                ;}
     break;
 
   case 9:
-#line 126 "dtc-parser.y"
+#line 130 "dtc-parser.y"
     {
                        (yyval.re) = (yyvsp[(1) - (1)].re);
                ;}
     break;
 
   case 10:
-#line 130 "dtc-parser.y"
+#line 134 "dtc-parser.y"
     {
                        (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
                ;}
     break;
 
   case 11:
-#line 137 "dtc-parser.y"
+#line 141 "dtc-parser.y"
     {
                        (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
                ;}
     break;
 
   case 12:
-#line 141 "dtc-parser.y"
+#line 145 "dtc-parser.y"
     {
                        (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
                ;}
     break;
 
   case 13:
-#line 148 "dtc-parser.y"
+#line 152 "dtc-parser.y"
     {
                        (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
                ;}
     break;
 
   case 14:
-#line 155 "dtc-parser.y"
+#line 159 "dtc-parser.y"
     {
                        (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
                ;}
     break;
 
   case 15:
-#line 162 "dtc-parser.y"
+#line 166 "dtc-parser.y"
     {
                        (yyval.proplist) = NULL;
                ;}
     break;
 
   case 16:
-#line 166 "dtc-parser.y"
+#line 170 "dtc-parser.y"
     {
                        (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
                ;}
     break;
 
   case 17:
-#line 173 "dtc-parser.y"
+#line 177 "dtc-parser.y"
     {
                        (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
                ;}
     break;
 
   case 18:
-#line 177 "dtc-parser.y"
+#line 181 "dtc-parser.y"
     {
                        (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
                ;}
     break;
 
   case 19:
-#line 184 "dtc-parser.y"
+#line 188 "dtc-parser.y"
     {
                        (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
                ;}
     break;
 
   case 20:
-#line 188 "dtc-parser.y"
+#line 192 "dtc-parser.y"
     {
                        (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
                ;}
     break;
 
   case 21:
-#line 192 "dtc-parser.y"
+#line 196 "dtc-parser.y"
     {
                        (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
                ;}
     break;
 
   case 22:
-#line 196 "dtc-parser.y"
+#line 200 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
                ;}
     break;
 
   case 23:
-#line 200 "dtc-parser.y"
+#line 204 "dtc-parser.y"
     {
-                       (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
+                       struct search_path path = { srcpos_file->dir, NULL, NULL };
+                       struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path);
+                       struct data d = empty_data;
+
+                       if ((yyvsp[(6) - (9)].addr) != 0)
+                               if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
+                                       yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
+                                                (unsigned long long)(yyvsp[(6) - (9)].addr),
+                                                (yyvsp[(4) - (9)].data).val, strerror(errno));
+
+                       d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr));
+
+                       (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
+                       dtc_close_file(file);
                ;}
     break;
 
   case 24:
-#line 207 "dtc-parser.y"
+#line 221 "dtc-parser.y"
     {
-                       (yyval.data) = empty_data;
+                       struct search_path path = { srcpos_file->dir, NULL, NULL };
+                       struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path);
+                       struct data d = empty_data;
+
+                       d = data_copy_file(file->file, -1);
+
+                       (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d);
+                       dtc_close_file(file);
                ;}
     break;
 
   case 25:
-#line 211 "dtc-parser.y"
+#line 232 "dtc-parser.y"
     {
-                       (yyval.data) = (yyvsp[(1) - (2)].data);
+                       (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
                ;}
     break;
 
   case 26:
-#line 215 "dtc-parser.y"
+#line 239 "dtc-parser.y"
     {
-                       (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
+                       (yyval.data) = empty_data;
                ;}
     break;
 
   case 27:
-#line 222 "dtc-parser.y"
+#line 243 "dtc-parser.y"
     {
-                       (yyval.data) = empty_data;
+                       (yyval.data) = (yyvsp[(1) - (2)].data);
                ;}
     break;
 
   case 28:
-#line 226 "dtc-parser.y"
+#line 247 "dtc-parser.y"
     {
-                       (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
+                       (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
                ;}
     break;
 
   case 29:
-#line 230 "dtc-parser.y"
+#line 254 "dtc-parser.y"
+    {
+                       (yyval.data) = empty_data;
+               ;}
+    break;
+
+  case 30:
+#line 258 "dtc-parser.y"
+    {
+                       (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
+               ;}
+    break;
+
+  case 31:
+#line 262 "dtc-parser.y"
     {
                        (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
                                                              (yyvsp[(2) - (2)].labelref)), -1);
                ;}
     break;
 
-  case 30:
-#line 235 "dtc-parser.y"
+  case 32:
+#line 267 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
                ;}
     break;
 
-  case 31:
-#line 242 "dtc-parser.y"
+  case 33:
+#line 274 "dtc-parser.y"
     {
                        (yyval.cbase) = 16;
                ;}
     break;
 
-  case 33:
-#line 250 "dtc-parser.y"
+  case 35:
+#line 282 "dtc-parser.y"
     {
                        (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
                ;}
     break;
 
-  case 34:
-#line 254 "dtc-parser.y"
+  case 36:
+#line 286 "dtc-parser.y"
     {
                        (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
                ;}
     break;
 
-  case 35:
-#line 261 "dtc-parser.y"
+  case 37:
+#line 293 "dtc-parser.y"
     {
                        (yyval.data) = empty_data;
                ;}
     break;
 
-  case 36:
-#line 265 "dtc-parser.y"
+  case 38:
+#line 297 "dtc-parser.y"
     {
                        (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
                ;}
     break;
 
-  case 37:
-#line 269 "dtc-parser.y"
+  case 39:
+#line 301 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
                ;}
     break;
 
-  case 38:
-#line 276 "dtc-parser.y"
+  case 40:
+#line 308 "dtc-parser.y"
     {
                        (yyval.nodelist) = NULL;
                ;}
     break;
 
-  case 39:
-#line 280 "dtc-parser.y"
+  case 41:
+#line 312 "dtc-parser.y"
     {
                        (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
                ;}
     break;
 
-  case 40:
-#line 284 "dtc-parser.y"
+  case 42:
+#line 316 "dtc-parser.y"
     {
-                       yyerror("syntax error: properties must precede subnodes\n");
+                       yyerror("syntax error: properties must precede subnodes");
                        YYERROR;
                ;}
     break;
 
-  case 41:
-#line 292 "dtc-parser.y"
+  case 43:
+#line 324 "dtc-parser.y"
     {
                        (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
                ;}
     break;
 
-  case 42:
-#line 299 "dtc-parser.y"
+  case 44:
+#line 331 "dtc-parser.y"
     {
                        (yyval.labelref) = NULL;
                ;}
     break;
 
-  case 43:
-#line 303 "dtc-parser.y"
+  case 45:
+#line 335 "dtc-parser.y"
     {
                        (yyval.labelref) = (yyvsp[(1) - (1)].labelref);
                ;}
@@ -1730,7 +1776,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 1734 "dtc-parser.tab.c"
+#line 1780 "dtc-parser.tab.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1950,21 +1996,32 @@ yyreturn:
 }
 
 
-#line 308 "dtc-parser.y"
+#line 340 "dtc-parser.y"
 
 
-void yyerror (char const *s)
+void yyerrorf(char const *s, ...)
 {
-       const char *fname = srcpos_filename_for_num(yylloc.filenum);
+       const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
+       va_list va;
+       va_start(va, s);
 
        if (strcmp(fname, "-") == 0)
                fname = "stdin";
 
-       fprintf(stderr, "%s:%d %s\n",
-               fname, yylloc.first_line, s);
+       fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
+       vfprintf(stderr, s, va);
+       fprintf(stderr, "\n");
+
+       treesource_error = 1;
+       va_end(va);
+}
+
+void yyerror (char const *s)
+{
+       yyerrorf("%s", s);
 }
 
-unsigned long long eval_literal(const char *s, int base, int bits)
+static unsigned long long eval_literal(const char *s, int base, int bits)
 {
        unsigned long long val;
        char *e;
index 4707b029ed25853dfb107c84c99ec4a1b551837b..ba99100d55c980e4281976df0ebbe4de31bdc541 100644 (file)
@@ -48,7 +48,8 @@
      DT_BYTE = 264,
      DT_STRING = 265,
      DT_LABEL = 266,
-     DT_REF = 267
+     DT_REF = 267,
+     DT_INCBIN = 268
    };
 #endif
 /* Tokens.  */
 #define DT_STRING 265
 #define DT_LABEL 266
 #define DT_REF 267
+#define DT_INCBIN 268
 
 
 
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 34 "dtc-parser.y"
+#line 37 "dtc-parser.y"
 {
        char *propnodename;
        char *literal;
        char *labelref;
        unsigned int cbase;
-       u8 byte;
+       uint8_t byte;
        struct data data;
 
-       u64 addr;
+       uint64_t addr;
        cell_t cell;
        struct property *prop;
        struct property *proplist;
@@ -86,7 +88,7 @@ typedef union YYSTYPE
        struct reserve_info *re;
 }
 /* Line 1489 of yacc.c.  */
-#line 90 "dtc-parser.tab.h"
+#line 92 "dtc-parser.tab.h"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
index 002ea7fef184ee5b9cc1aec663f262c7e5bd2bdf..b2ab562420ead9815ac83adf4372bece16e10f23 100644 (file)
 %locations
 
 %{
+#include <stdio.h>
+
 #include "dtc.h"
 #include "srcpos.h"
 
-int yylex(void);
-unsigned long long eval_literal(const char *s, int base, int bits);
+extern int yylex(void);
 
 extern struct boot_info *the_boot_info;
+extern int treesource_error;
 
+static unsigned long long eval_literal(const char *s, int base, int bits);
 %}
 
 %union {
@@ -36,10 +39,10 @@ extern struct boot_info *the_boot_info;
        char *literal;
        char *labelref;
        unsigned int cbase;
-       u8 byte;
+       uint8_t byte;
        struct data data;
 
-       u64 addr;
+       uint64_t addr;
        cell_t cell;
        struct property *prop;
        struct property *proplist;
@@ -58,6 +61,7 @@ extern struct boot_info *the_boot_info;
 %token <data> DT_STRING
 %token <labelref> DT_LABEL
 %token <labelref> DT_REF
+%token DT_INCBIN
 
 %type <data> propdata
 %type <data> propdataprefix
@@ -84,11 +88,11 @@ extern struct boot_info *the_boot_info;
 sourcefile:
          DT_V1 ';' memreserves devicetree
                {
-                       the_boot_info = build_boot_info($3, $4);
+                       the_boot_info = build_boot_info($3, $4, 0);
                }
        | v0_memreserves devicetree
                {
-                       the_boot_info = build_boot_info($1, $2);
+                       the_boot_info = build_boot_info($1, $2, 0);
                }
        ;
 
@@ -196,6 +200,34 @@ propdata:
                {
                        $$ = data_add_marker($1, REF_PATH, $2);
                }
+       | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
+               {
+                       struct search_path path = { srcpos_file->dir, NULL, NULL };
+                       struct dtc_file *file = dtc_open_file($4.val, &path);
+                       struct data d = empty_data;
+
+                       if ($6 != 0)
+                               if (fseek(file->file, $6, SEEK_SET) != 0)
+                                       yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
+                                                (unsigned long long)$6,
+                                                $4.val, strerror(errno));
+
+                       d = data_copy_file(file->file, $8);
+
+                       $$ = data_merge($1, d);
+                       dtc_close_file(file);
+               }
+       | propdataprefix DT_INCBIN '(' DT_STRING ')'
+               {
+                       struct search_path path = { srcpos_file->dir, NULL, NULL };
+                       struct dtc_file *file = dtc_open_file($4.val, &path);
+                       struct data d = empty_data;
+
+                       d = data_copy_file(file->file, -1);
+
+                       $$ = data_merge($1, d);
+                       dtc_close_file(file);
+               }
        | propdata DT_LABEL
                {
                        $$ = data_add_marker($1, LABEL, $2);
@@ -282,7 +314,7 @@ subnodes:
                }
        | subnode propdef
                {
-                       yyerror("syntax error: properties must precede subnodes\n");
+                       yyerror("syntax error: properties must precede subnodes");
                        YYERROR;
                }
        ;
@@ -307,18 +339,29 @@ label:
 
 %%
 
-void yyerror (char const *s)
+void yyerrorf(char const *s, ...)
 {
-       const char *fname = srcpos_filename_for_num(yylloc.filenum);
+       const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
+       va_list va;
+       va_start(va, s);
 
        if (strcmp(fname, "-") == 0)
                fname = "stdin";
 
-       fprintf(stderr, "%s:%d %s\n",
-               fname, yylloc.first_line, s);
+       fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
+       vfprintf(stderr, s, va);
+       fprintf(stderr, "\n");
+
+       treesource_error = 1;
+       va_end(va);
+}
+
+void yyerror (char const *s)
+{
+       yyerrorf("%s", s);
 }
 
-unsigned long long eval_literal(const char *s, int base, int bits)
+static unsigned long long eval_literal(const char *s, int base, int bits)
 {
        unsigned long long val;
        char *e;
index 01131d7c2d5ef95c528b087d8e495ccc005a8cb6..d8fd43b4ac1a517a339e30e095f2a28544a1b906 100644 (file)
@@ -55,7 +55,7 @@ char *join_path(const char *path, const char *name)
        return str;
 }
 
-void fill_fullpaths(struct node *tree, const char *prefix)
+static void fill_fullpaths(struct node *tree, const char *prefix)
 {
        struct node *child;
        const char *unit;
@@ -106,7 +106,7 @@ static void  __attribute__ ((noreturn)) usage(void)
        fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
        fprintf(stderr, "\t-v\n");
        fprintf(stderr, "\t\tPrint DTC version and exit\n");
-       exit(2);
+       exit(3);
 }
 
 int main(int argc, char *argv[])
@@ -118,10 +118,9 @@ int main(int argc, char *argv[])
        int force = 0, check = 0;
        const char *arg;
        int opt;
-       FILE *inf = NULL;
        FILE *outf = NULL;
        int outversion = DEFAULT_FDT_VERSION;
-       int boot_cpuid_phys = 0xfeedbeef;
+       long long cmdline_boot_cpuid = -1;
 
        quiet      = 0;
        reservenum = 0;
@@ -161,11 +160,11 @@ int main(int argc, char *argv[])
                        quiet++;
                        break;
                case 'b':
-                       boot_cpuid_phys = strtol(optarg, NULL, 0);
+                       cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
                        break;
                case 'v':
-                   printf("Version: %s\n", DTC_VERSION);
-                   exit(0);
+                       printf("Version: %s\n", DTC_VERSION);
+                       exit(0);
                case 'h':
                default:
                        usage();
@@ -180,31 +179,27 @@ int main(int argc, char *argv[])
                arg = argv[optind];
 
        /* minsize and padsize are mutually exclusive */
-       if ((minsize) && (padsize)) {
+       if (minsize && padsize)
                die("Can't set both -p and -S\n");
-       }
 
        fprintf(stderr, "DTC: %s->%s  on file \"%s\"\n",
                inform, outform, arg);
 
-       if (streq(inform, "dts")) {
+       if (streq(inform, "dts"))
                bi = dt_from_source(arg);
-       } else if (streq(inform, "fs")) {
+       else if (streq(inform, "fs"))
                bi = dt_from_fs(arg);
-       } else if(streq(inform, "dtb")) {
-               inf = dtc_open_file(arg);
-               bi = dt_from_blob(inf);
-       } else {
+       else if(streq(inform, "dtb"))
+               bi = dt_from_blob(arg);
+       else
                die("Unknown input format \"%s\"\n", inform);
-       }
 
-       if (inf && (inf != stdin))
-               fclose(inf);
+       if (cmdline_boot_cpuid != -1)
+               bi->boot_cpuid_phys = cmdline_boot_cpuid;
 
-       if (! bi || ! bi->dt)
-               die("Couldn't read input tree\n");
+       fill_fullpaths(bi->dt, "");
+       process_checks(force, bi);
 
-       process_checks(force, bi, check, outversion, boot_cpuid_phys);
 
        if (streq(outname, "-")) {
                outf = stdout;
@@ -218,9 +213,9 @@ int main(int argc, char *argv[])
        if (streq(outform, "dts")) {
                dt_to_source(outf, bi);
        } else if (streq(outform, "dtb")) {
-               dt_to_blob(outf, bi, outversion, boot_cpuid_phys);
+               dt_to_blob(outf, bi, outversion);
        } else if (streq(outform, "asm")) {
-               dt_to_asm(outf, bi, outversion, boot_cpuid_phys);
+               dt_to_asm(outf, bi, outversion);
        } else if (streq(outform, "null")) {
                /* do nothing */
        } else {
index 65281777a167294e7385391efe751876f4d05001..08d54c8700863a84ab08c26ef699af4bce99c431 100644 (file)
 #include <ctype.h>
 #include <errno.h>
 #include <unistd.h>
-#include <netinet/in.h>
-#include <endian.h>
-#include <byteswap.h>
 
+#include <libfdt_env.h>
 #include <fdt.h>
 
 #define DEFAULT_FDT_VERSION    17
@@ -75,25 +73,8 @@ static inline void *xrealloc(void *p, size_t len)
        return new;
 }
 
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-typedef u32 cell_t;
+typedef uint32_t cell_t;
 
-#define cpu_to_be16(x) htons(x)
-#define be16_to_cpu(x) ntohs(x)
-
-#define cpu_to_be32(x) htonl(x)
-#define be32_to_cpu(x) ntohl(x)
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define cpu_to_be64(x) (x)
-#define be64_to_cpu(x) (x)
-#else
-#define cpu_to_be64(x) bswap_64(x)
-#define be64_to_cpu(x) bswap_64(x)
-#endif
 
 #define streq(a, b)    (strcmp((a), (b)) == 0)
 #define strneq(a, b, n)        (strncmp((a), (b), (n)) == 0)
@@ -118,7 +99,6 @@ struct  marker {
 struct data {
        int len;
        char *val;
-       int asize;
        struct marker *markers;
 };
 
@@ -145,7 +125,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
 struct data data_merge(struct data d1, struct data d2);
 struct data data_append_cell(struct data d, cell_t word);
 struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
-struct data data_append_addr(struct data d, u64 addr);
+struct data data_append_addr(struct data d, uint64_t addr);
 struct data data_append_byte(struct data d, uint8_t byte);
 struct data data_append_zeroes(struct data d, int len);
 struct data data_append_align(struct data d, int align);
@@ -223,7 +203,7 @@ struct reserve_info {
        char *label;
 };
 
-struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label);
+struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
 struct reserve_info *chain_reserve_entry(struct reserve_info *first,
                                         struct reserve_info *list);
 struct reserve_info *add_reserve_entry(struct reserve_info *list,
@@ -233,24 +213,22 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
 struct boot_info {
        struct reserve_info *reservelist;
        struct node *dt;                /* the device tree */
+       uint32_t boot_cpuid_phys;
 };
 
 struct boot_info *build_boot_info(struct reserve_info *reservelist,
-                                 struct node *tree);
+                                 struct node *tree, uint32_t boot_cpuid_phys);
 
 /* Checks */
 
-void process_checks(int force, struct boot_info *bi,
-                   int checkflag, int outversion, int boot_cpuid_phys);
+void process_checks(int force, struct boot_info *bi);
 
 /* Flattened trees */
 
-void dt_to_blob(FILE *f, struct boot_info *bi, int version,
-               int boot_cpuid_phys);
-void dt_to_asm(FILE *f, struct boot_info *bi, int version,
-              int boot_cpuid_phys);
+void dt_to_blob(FILE *f, struct boot_info *bi, int version);
+void dt_to_asm(FILE *f, struct boot_info *bi, int version);
 
-struct boot_info *dt_from_blob(FILE *f);
+struct boot_info *dt_from_blob(const char *fname);
 
 /* Tree source */
 
@@ -264,6 +242,5 @@ struct boot_info *dt_from_fs(const char *dirname);
 /* misc */
 
 char *join_path(const char *path, const char *name);
-void fill_fullpaths(struct node *tree, const char *prefix);
 
 #endif /* _DTC_H */
index a7cfb843d3342413882a5d3583b725bdfc30e0cd..76acd28c068db81195548369019b577d4aee5ddb 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "dtc.h"
+#include "srcpos.h"
 
 #define FTF_FULLPATH   0x1
 #define FTF_VARALIGN   0x2
@@ -162,28 +163,18 @@ static void asm_emit_data(void *e, struct data d)
 {
        FILE *f = e;
        int off = 0;
-       struct marker *m;
+       struct marker *m = d.markers;
 
-       m = d.markers;
-       while (m) {
-               if (m->type == LABEL)
-                       emit_offset_label(f, m->ref, m->offset);
-               m = m->next;
-       }
+       for_each_marker_of_type(m, LABEL)
+               emit_offset_label(f, m->ref, m->offset);
 
-       while ((d.len - off) >= sizeof(u32)) {
+       while ((d.len - off) >= sizeof(uint32_t)) {
                fprintf(f, "\t.long\t0x%x\n",
-                       be32_to_cpu(*((u32 *)(d.val+off))));
-               off += sizeof(u32);
-       }
-
-       if ((d.len - off) >= sizeof(u16)) {
-               fprintf(f, "\t.short\t0x%hx\n",
-                       be16_to_cpu(*((u16 *)(d.val+off))));
-               off += sizeof(u16);
+                       fdt32_to_cpu(*((uint32_t *)(d.val+off))));
+               off += sizeof(uint32_t);
        }
 
-       if ((d.len - off) >= 1) {
+       while ((d.len - off) >= 1) {
                fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
                off += 1;
        }
@@ -336,29 +327,28 @@ static void make_fdt_header(struct fdt_header *fdt,
 
        memset(fdt, 0xff, sizeof(*fdt));
 
-       fdt->magic = cpu_to_be32(FDT_MAGIC);
-       fdt->version = cpu_to_be32(vi->version);
-       fdt->last_comp_version = cpu_to_be32(vi->last_comp_version);
+       fdt->magic = cpu_to_fdt32(FDT_MAGIC);
+       fdt->version = cpu_to_fdt32(vi->version);
+       fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version);
 
        /* Reserve map should be doubleword aligned */
        reserve_off = ALIGN(vi->hdr_size, 8);
 
-       fdt->off_mem_rsvmap = cpu_to_be32(reserve_off);
-       fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
-       fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize
+       fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off);
+       fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize);
+       fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize
                                          + dtsize);
-       fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
+       fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize);
 
        if (vi->flags & FTF_BOOTCPUID)
-               fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
+               fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys);
        if (vi->flags & FTF_STRTABSIZE)
-               fdt->size_dt_strings = cpu_to_be32(strsize);
+               fdt->size_dt_strings = cpu_to_fdt32(strsize);
        if (vi->flags & FTF_STRUCTSIZE)
-               fdt->size_dt_struct = cpu_to_be32(dtsize);
+               fdt->size_dt_struct = cpu_to_fdt32(dtsize);
 }
 
-void dt_to_blob(FILE *f, struct boot_info *bi, int version,
-               int boot_cpuid_phys)
+void dt_to_blob(FILE *f, struct boot_info *bi, int version)
 {
        struct version_info *vi = NULL;
        int i;
@@ -383,26 +373,26 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version,
 
        /* Make header */
        make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
-                       boot_cpuid_phys);
+                       bi->boot_cpuid_phys);
 
        /*
         * If the user asked for more space than is used, adjust the totalsize.
         */
        if (minsize > 0) {
-               padlen = minsize - be32_to_cpu(fdt.totalsize);
+               padlen = minsize - fdt32_to_cpu(fdt.totalsize);
                if ((padlen < 0) && (quiet < 1))
                        fprintf(stderr,
                                "Warning: blob size %d >= minimum size %d\n",
-                               be32_to_cpu(fdt.totalsize), minsize);
+                               fdt32_to_cpu(fdt.totalsize), minsize);
        }
 
        if (padsize > 0)
                padlen = padsize;
 
        if (padlen > 0) {
-               int tsize = be32_to_cpu(fdt.totalsize);
+               int tsize = fdt32_to_cpu(fdt.totalsize);
                tsize += padlen;
-               fdt.totalsize = cpu_to_be32(tsize);
+               fdt.totalsize = cpu_to_fdt32(tsize);
        }
 
        /*
@@ -410,7 +400,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version,
         * the reserve buffer, add the reserve map terminating zeroes,
         * the device tree itself, and finally the strings.
         */
-       blob = data_append_data(blob, &fdt, sizeof(fdt));
+       blob = data_append_data(blob, &fdt, vi->hdr_size);
        blob = data_append_align(blob, 8);
        blob = data_merge(blob, reservebuf);
        blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
@@ -449,7 +439,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf)
        }
 }
 
-void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
+void dt_to_asm(FILE *f, struct boot_info *bi, int version)
 {
        struct version_info *vi = NULL;
        int i;
@@ -489,7 +479,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
 
        if (vi->flags & FTF_BOOTCPUID)
                fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
-                       boot_cpuid_phys);
+                       bi->boot_cpuid_phys);
 
        if (vi->flags & FTF_STRTABSIZE)
                fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
@@ -579,15 +569,15 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len)
        inb->ptr += len;
 }
 
-static u32 flat_read_word(struct inbuf *inb)
+static uint32_t flat_read_word(struct inbuf *inb)
 {
-       u32 val;
+       uint32_t val;
 
        assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
 
        flat_read_chunk(inb, &val, sizeof(val));
 
-       return be32_to_cpu(val);
+       return fdt32_to_cpu(val);
 }
 
 static void flat_realign(struct inbuf *inb, int align)
@@ -615,7 +605,7 @@ static char *flat_read_string(struct inbuf *inb)
 
        inb->ptr += len;
 
-       flat_realign(inb, sizeof(u32));
+       flat_realign(inb, sizeof(uint32_t));
 
        return str;
 }
@@ -632,7 +622,7 @@ static struct data flat_read_data(struct inbuf *inb, int len)
 
        flat_read_chunk(inb, d.val, len);
 
-       flat_realign(inb, sizeof(u32));
+       flat_realign(inb, sizeof(uint32_t));
 
        return d;
 }
@@ -659,7 +649,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
 static struct property *flat_read_property(struct inbuf *dtbuf,
                                           struct inbuf *strbuf, int flags)
 {
-       u32 proplen, stroff;
+       uint32_t proplen, stroff;
        char *name;
        struct data val;
 
@@ -693,8 +683,8 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
        p = inb->ptr;
        while (1) {
                flat_read_chunk(inb, &re, sizeof(re));
-               re.address  = be64_to_cpu(re.address);
-               re.size = be64_to_cpu(re.size);
+               re.address  = fdt64_to_cpu(re.address);
+               re.size = fdt64_to_cpu(re.size);
                if (re.size == 0)
                        break;
 
@@ -708,77 +698,37 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
 
 static char *nodename_from_path(const char *ppath, const char *cpath)
 {
-       const char *lslash;
        int plen;
 
-       lslash = strrchr(cpath, '/');
-       if (! lslash)
-               return NULL;
-
-       plen = lslash - cpath;
-
-       if (streq(cpath, "/") && streq(ppath, ""))
-               return "";
-
-       if ((plen == 0) && streq(ppath, "/"))
-               return strdup(lslash+1);
-
-       if (! strneq(ppath, cpath, plen))
-               return NULL;
-
-       return strdup(lslash+1);
-}
-
-static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
-static const char UNITCHAR[] = "0123456789abcdef,";
-
-static int check_node_name(const char *name)
-{
-       const char *atpos;
-       int basenamelen;
+       plen = strlen(ppath);
 
-       atpos = strrchr(name, '@');
+       if (!strneq(ppath, cpath, plen))
+               die("Path \"%s\" is not valid as a child of \"%s\"\n",
+                   cpath, ppath);
 
-       if (atpos)
-               basenamelen = atpos - name;
-       else
-               basenamelen = strlen(name);
-
-       if (strspn(name, PROPCHAR) < basenamelen)
-               return -1;
+       /* root node is a special case */
+       if (!streq(ppath, "/"))
+               plen++;
 
-       if (atpos
-           && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
-               return -1;
-
-       return basenamelen;
+       return strdup(cpath + plen);
 }
 
 static struct node *unflatten_tree(struct inbuf *dtbuf,
                                   struct inbuf *strbuf,
-                                  const char *parent_path, int flags)
+                                  const char *parent_flatname, int flags)
 {
        struct node *node;
-       u32 val;
+       char *flatname;
+       uint32_t val;
 
        node = build_node(NULL, NULL);
 
-       if (flags & FTF_FULLPATH) {
-               node->fullpath = flat_read_string(dtbuf);
-               node->name = nodename_from_path(parent_path, node->fullpath);
-
-               if (! node->name)
-                       die("Path \"%s\" is not valid as a child of \"%s\"\n",
-                           node->fullpath, parent_path);
-       } else {
-               node->name = flat_read_string(dtbuf);
-               node->fullpath = join_path(parent_path, node->name);
-       }
+       flatname = flat_read_string(dtbuf);
 
-       node->basenamelen = check_node_name(node->name);
-       if (node->basenamelen < 0) {
-               fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name);
-       }
+       if (flags & FTF_FULLPATH)
+               node->name = nodename_from_path(parent_flatname, flatname);
+       else
+               node->name = flatname;
 
        do {
                struct property *prop;
@@ -795,8 +745,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
                        break;
 
                case FDT_BEGIN_NODE:
-                       child = unflatten_tree(dtbuf,strbuf, node->fullpath,
-                                              flags);
+                       child = unflatten_tree(dtbuf,strbuf, flatname, flags);
                        add_child(node, child);
                        break;
 
@@ -825,10 +774,11 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
 }
 
 
-struct boot_info *dt_from_blob(FILE *f)
+struct boot_info *dt_from_blob(const char *fname)
 {
-       u32 magic, totalsize, version, size_str, size_dt;
-       u32 off_dt, off_str, off_mem_rsvmap;
+       struct dtc_file *dtcf;
+       uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
+       uint32_t off_dt, off_str, off_mem_rsvmap;
        int rc;
        char *blob;
        struct fdt_header *fdt;
@@ -838,54 +788,56 @@ struct boot_info *dt_from_blob(FILE *f)
        int sizeleft;
        struct reserve_info *reservelist;
        struct node *tree;
-       u32 val;
+       uint32_t val;
        int flags = 0;
 
-       rc = fread(&magic, sizeof(magic), 1, f);
-       if (ferror(f))
+       dtcf = dtc_open_file(fname, NULL);
+
+       rc = fread(&magic, sizeof(magic), 1, dtcf->file);
+       if (ferror(dtcf->file))
                die("Error reading DT blob magic number: %s\n",
                    strerror(errno));
        if (rc < 1) {
-               if (feof(f))
+               if (feof(dtcf->file))
                        die("EOF reading DT blob magic number\n");
                else
                        die("Mysterious short read reading magic number\n");
        }
 
-       magic = be32_to_cpu(magic);
+       magic = fdt32_to_cpu(magic);
        if (magic != FDT_MAGIC)
                die("Blob has incorrect magic number\n");
 
-       rc = fread(&totalsize, sizeof(totalsize), 1, f);
-       if (ferror(f))
+       rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
+       if (ferror(dtcf->file))
                die("Error reading DT blob size: %s\n", strerror(errno));
        if (rc < 1) {
-               if (feof(f))
+               if (feof(dtcf->file))
                        die("EOF reading DT blob size\n");
                else
                        die("Mysterious short read reading blob size\n");
        }
 
-       totalsize = be32_to_cpu(totalsize);
+       totalsize = fdt32_to_cpu(totalsize);
        if (totalsize < FDT_V1_SIZE)
                die("DT blob size (%d) is too small\n", totalsize);
 
        blob = xmalloc(totalsize);
 
        fdt = (struct fdt_header *)blob;
-       fdt->magic = cpu_to_be32(magic);
-       fdt->totalsize = cpu_to_be32(totalsize);
+       fdt->magic = cpu_to_fdt32(magic);
+       fdt->totalsize = cpu_to_fdt32(totalsize);
 
        sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
        p = blob + sizeof(magic)  + sizeof(totalsize);
 
        while (sizeleft) {
-               if (feof(f))
+               if (feof(dtcf->file))
                        die("EOF before reading %d bytes of DT blob\n",
                            totalsize);
 
-               rc = fread(p, 1, sizeleft, f);
-               if (ferror(f))
+               rc = fread(p, 1, sizeleft, dtcf->file);
+               if (ferror(dtcf->file))
                        die("Error reading DT blob: %s\n",
                            strerror(errno));
 
@@ -893,19 +845,11 @@ struct boot_info *dt_from_blob(FILE *f)
                p += rc;
        }
 
-       off_dt = be32_to_cpu(fdt->off_dt_struct);
-       off_str = be32_to_cpu(fdt->off_dt_strings);
-       off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap);
-       version = be32_to_cpu(fdt->version);
-
-       fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
-       fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
-       fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
-       fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
-       fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
-       fprintf(stderr, "\tversion:\t\t0x%x\n", version );
-       fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
-               be32_to_cpu(fdt->last_comp_version));
+       off_dt = fdt32_to_cpu(fdt->off_dt_struct);
+       off_str = fdt32_to_cpu(fdt->off_dt_strings);
+       off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap);
+       version = fdt32_to_cpu(fdt->version);
+       boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys);
 
        if (off_mem_rsvmap >= totalsize)
                die("Mem Reserve structure offset exceeds total size\n");
@@ -916,21 +860,17 @@ struct boot_info *dt_from_blob(FILE *f)
        if (off_str > totalsize)
                die("String table offset exceeds total size\n");
 
-       if (version >= 2)
-               fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
-                       be32_to_cpu(fdt->boot_cpuid_phys));
-
-       size_str = -1;
        if (version >= 3) {
-               size_str = be32_to_cpu(fdt->size_dt_strings);
-               fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
+               uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings);
                if (off_str+size_str > totalsize)
                        die("String table extends past total size\n");
+               inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
+       } else {
+               inbuf_init(&strbuf, blob + off_str, blob + totalsize);
        }
 
        if (version >= 17) {
-               size_dt = be32_to_cpu(fdt->size_dt_struct);
-               fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
+               size_dt = fdt32_to_cpu(fdt->size_dt_struct);
                if (off_dt+size_dt > totalsize)
                        die("Structure block extends past total size\n");
        }
@@ -944,10 +884,6 @@ struct boot_info *dt_from_blob(FILE *f)
        inbuf_init(&memresvbuf,
                   blob + off_mem_rsvmap, blob + totalsize);
        inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
-       if (size_str >= 0)
-               inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
-       else
-               inbuf_init(&strbuf, blob + off_str, blob + totalsize);
 
        reservelist = flat_read_mem_reserve(&memresvbuf);
 
@@ -964,5 +900,7 @@ struct boot_info *dt_from_blob(FILE *f)
 
        free(blob);
 
-       return build_boot_info(reservelist, tree);
+       dtc_close_file(dtcf);
+
+       return build_boot_info(reservelist, tree, boot_cpuid_phys);
 }
index 2a160a46998ee99ad3189a948a5f6894a63e75a6..766b2694d93589fe39ea6313dbae7b1ce5a21daa 100644 (file)
@@ -31,8 +31,8 @@ static struct node *read_fstree(const char *dirname)
        struct node *tree;
 
        d = opendir(dirname);
-       if (! d)
-               die("opendir(): %s\n", strerror(errno));
+       if (!d)
+               die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
 
        tree = build_node(NULL, NULL);
 
@@ -87,8 +87,6 @@ struct boot_info *dt_from_fs(const char *dirname)
        tree = read_fstree(dirname);
        tree = name_node(tree, "", NULL);
 
-       fill_fullpaths(tree, "");
-
-       return build_boot_info(NULL, tree);
+       return build_boot_info(NULL, tree, 0);
 }
 
diff --git a/arch/powerpc/boot/dtc-src/libfdt_env.h b/arch/powerpc/boot/dtc-src/libfdt_env.h
new file mode 100644 (file)
index 0000000..449bf60
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#define _B(n)  ((unsigned long long)((uint8_t *)&x)[n])
+static inline uint32_t fdt32_to_cpu(uint32_t x)
+{
+       return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3);
+}
+#define cpu_to_fdt32(x) fdt32_to_cpu(x)
+
+static inline uint64_t fdt64_to_cpu(uint64_t x)
+{
+       return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32)
+               | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7);
+}
+#define cpu_to_fdt64(x) fdt64_to_cpu(x)
+#undef _B
+
+#endif /* _LIBFDT_ENV_H */
index 6ba0846b4310a5dd97e0ae4729afbe8a4203af4d..0ca3de550b3ff7d1ef6d437849061238275b0d4d 100644 (file)
@@ -115,6 +115,7 @@ void add_child(struct node *parent, struct node *child)
        struct node **p;
 
        child->next_sibling = NULL;
+       child->parent = parent;
 
        p = &parent->children;
        while (*p)
@@ -123,7 +124,8 @@ void add_child(struct node *parent, struct node *child)
        *p = child;
 }
 
-struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label)
+struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
+                                        char *label)
 {
        struct reserve_info *new = xmalloc(sizeof(*new));
 
@@ -165,13 +167,14 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
 }
 
 struct boot_info *build_boot_info(struct reserve_info *reservelist,
-                                 struct node *tree)
+                                 struct node *tree, uint32_t boot_cpuid_phys)
 {
        struct boot_info *bi;
 
        bi = xmalloc(sizeof(*bi));
        bi->reservelist = reservelist;
        bi->dt = tree;
+       bi->boot_cpuid_phys = boot_cpuid_phys;
 
        return bi;
 }
@@ -202,7 +205,7 @@ struct property *get_property(struct node *node, const char *propname)
 cell_t propval_cell(struct property *prop)
 {
        assert(prop->val.len == sizeof(cell_t));
-       return be32_to_cpu(*((cell_t *)prop->val.val));
+       return fdt32_to_cpu(*((cell_t *)prop->val.val));
 }
 
 struct node *get_subnode(struct node *node, const char *nodename)
index 352b0fe06fde1f6e9b112ffdf01941d8a5398de5..9641b7628b4de60b8d476f5329334b6dc6a10144 100644 (file)
 #include "dtc.h"
 #include "srcpos.h"
 
-
-/*
- * Record the complete unique set of opened file names.
- * Primarily used to cache source position file names.
- */
-#define MAX_N_FILE_NAMES       (100)
-
-const char *file_names[MAX_N_FILE_NAMES];
-static int n_file_names = 0;
-
 /*
  * Like yylineno, this is the current open file pos.
  */
 
-int srcpos_filenum = -1;
-
+struct dtc_file *srcpos_file;
 
-
-FILE *dtc_open_file(const char *fname)
+static int dtc_open_one(struct dtc_file *file,
+                        const char *search,
+                        const char *fname)
 {
-       FILE *f;
+       char *fullname;
 
-       if (lookup_file_name(fname, 1) < 0)
-               die("Too many files opened\n");
+       if (search) {
+               fullname = xmalloc(strlen(search) + strlen(fname) + 2);
 
-       if (streq(fname, "-"))
-               f = stdin;
-       else
-               f = fopen(fname, "r");
+               strcpy(fullname, search);
+               strcat(fullname, "/");
+               strcat(fullname, fname);
+       } else {
+               fullname = strdup(fname);
+       }
 
-       if (! f)
-               die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
+       file->file = fopen(fullname, "r");
+       if (!file->file) {
+               free(fullname);
+               return 0;
+       }
 
-       return f;
+       file->name = fullname;
+       return 1;
 }
 
 
+struct dtc_file *dtc_open_file(const char *fname,
+                               const struct search_path *search)
+{
+       static const struct search_path default_search = { NULL, NULL, NULL };
 
-/*
- * Locate and optionally add filename fname in the file_names[] array.
- *
- * If the filename is currently not in the array and the boolean
- * add_it is non-zero, an attempt to add the filename will be made.
- *
- * Returns;
- *    Index [0..MAX_N_FILE_NAMES) where the filename is kept
- *    -1 if the name can not be recorded
- */
+       struct dtc_file *file;
+       const char *slash;
 
-int lookup_file_name(const char *fname, int add_it)
-{
-       int i;
+       file = xmalloc(sizeof(struct dtc_file));
 
-       for (i = 0; i < n_file_names; i++) {
-               if (strcmp(file_names[i], fname) == 0)
-                       return i;
+       slash = strrchr(fname, '/');
+       if (slash) {
+               char *dir = xmalloc(slash - fname + 1);
+
+               memcpy(dir, fname, slash - fname);
+               dir[slash - fname] = 0;
+               file->dir = dir;
+       } else {
+               file->dir = NULL;
        }
 
-       if (add_it) {
-               if (n_file_names < MAX_N_FILE_NAMES) {
-                       file_names[n_file_names] = strdup(fname);
-                       return n_file_names++;
-               }
+       if (streq(fname, "-")) {
+               file->name = "stdin";
+               file->file = stdin;
+               return file;
        }
 
-       return -1;
-}
+       if (fname[0] == '/') {
+               file->file = fopen(fname, "r");
+               if (!file->file)
+                       goto fail;
+
+               file->name = strdup(fname);
+               return file;
+       }
 
+       if (!search)
+               search = &default_search;
 
-const char *srcpos_filename_for_num(int filenum)
-{
-       if (0 <= filenum && filenum < n_file_names) {
-               return file_names[filenum];
+       while (search) {
+               if (dtc_open_one(file, search->dir, fname))
+                       return file;
+
+               if (errno != ENOENT)
+                       goto fail;
+
+               search = search->next;
        }
 
-       return 0;
+fail:
+       die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
 }
 
-
-const char *srcpos_get_filename(void)
+void dtc_close_file(struct dtc_file *file)
 {
-       return srcpos_filename_for_num(srcpos_filenum);
+       if (fclose(file->file))
+               die("Error closing \"%s\": %s\n", file->name, strerror(errno));
+
+       free(file->dir);
+       free(file);
 }
index ce7ab5ba5b4659ab90426f62ed7a2182187ca805..e17c7c04db8ea4c17d4dfc94e7082b6eb9f296cb 100644 (file)
  * array of all opened filenames.
  */
 
+#include <stdio.h>
+
+struct dtc_file {
+       char *dir;
+       const char *name;
+       FILE *file;
+};
+
 #if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
 typedef struct YYLTYPE {
     int first_line;
     int first_column;
     int last_line;
     int last_column;
-    int filenum;
+    struct dtc_file *file;
 } YYLTYPE;
 
 #define YYLTYPE_IS_DECLARED    1
@@ -48,7 +56,7 @@ typedef struct YYLTYPE {
          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-         (Current).filenum      = YYRHSLOC (Rhs, N).filenum;           \
+         (Current).file         = YYRHSLOC (Rhs, N).file;              \
        }                                                               \
       else                                                             \
        {                                                               \
@@ -56,20 +64,22 @@ typedef struct YYLTYPE {
            YYRHSLOC (Rhs, 0).last_line;                                \
          (Current).first_column = (Current).last_column =              \
            YYRHSLOC (Rhs, 0).last_column;                              \
-         (Current).filenum      = YYRHSLOC (Rhs, 0).filenum;           \
+         (Current).file         = YYRHSLOC (Rhs, 0).file;              \
        }                                                               \
     while (YYID (0))
 
 
 
 extern void yyerror(char const *);
+extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2)));
 
-extern int srcpos_filenum;
+extern struct dtc_file *srcpos_file;
 
-extern int push_input_file(const char *filename);
-extern int pop_input_file(void);
+struct search_path {
+       const char *dir; /* NULL for current directory */
+       struct search_path *prev, *next;
+};
 
-extern FILE *dtc_open_file(const char *fname);
-extern int lookup_file_name(const char *fname, int add_it);
-extern const char *srcpos_filename_for_num(int filenum);
-const char *srcpos_get_filename(void);
+extern struct dtc_file *dtc_open_file(const char *fname,
+                                      const struct search_path *search);
+extern void dtc_close_file(struct dtc_file *file);
index a6a7767976364498a99b1a3c6c7d4d8f6071446a..ebeb6eb27907db69cd113ba0de8fa9dfd856d25f 100644 (file)
 
 extern FILE *yyin;
 extern int yyparse(void);
-extern void yyerror(char const *);
 
 struct boot_info *the_boot_info;
+int treesource_error;
 
 struct boot_info *dt_from_source(const char *fname)
 {
        the_boot_info = NULL;
+       treesource_error = 0;
 
-       push_input_file(fname);
+       srcpos_file = dtc_open_file(fname, NULL);
+       yyin = srcpos_file->file;
 
        if (yyparse() != 0)
-               return NULL;
+               die("Unable to parse input tree\n");
 
-       fill_fullpaths(the_boot_info->dt, "");
+       if (treesource_error)
+               die("Syntax error parsing input tree\n");
 
        return the_boot_info;
 }
@@ -144,7 +147,7 @@ static void write_propval_cells(FILE *f, struct data val)
                        m = m->next;
                }
 
-               fprintf(f, "0x%x", be32_to_cpu(*cp++));
+               fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
                if ((void *)cp >= propend)
                        break;
                fprintf(f, " ");
@@ -173,7 +176,7 @@ static void write_propval_bytes(FILE *f, struct data val)
                }
 
                fprintf(f, "%02hhx", *bp++);
-               if ((void *)bp >= propend)
+               if ((const void *)bp >= propend)
                        break;
                fprintf(f, " ");
        }
index 6c343031538ee00658c5f4424a3412afc59a5d21..658ff42429d64eba3e37d34c1f66d760631814bd 100644 (file)
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.0.0-gd6f9b62f"
+#define DTC_VERSION "DTC 1.2.0"
diff --git a/arch/powerpc/boot/dts/arches.dts b/arch/powerpc/boot/dts/arches.dts
new file mode 100644 (file)
index 0000000..d9113b1
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Device Tree Source for AMCC Arches (dual 460GT board)
+ *
+ * (C) Copyright 2008 Applied Micro Circuits Corporation
+ * Victor Gallardo <vgallardo@amcc.com>
+ * Adam Graham <agraham@amcc.com>
+ *
+ * Based on the glacier.dts file
+ *   Stefan Roese <sr@denx.de>
+ *   Copyright 2008 DENX Software Engineering
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/dts-v1/;
+
+/ {
+       #address-cells = <2>;
+       #size-cells = <1>;
+       model = "amcc,arches";
+       compatible = "amcc,arches";
+       dcr-parent = <&{/cpus/cpu@0}>;
+
+       aliases {
+               ethernet0 = &EMAC0;
+               ethernet1 = &EMAC1;
+               ethernet2 = &EMAC2;
+               serial0 = &UART0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,460GT";
+                       reg = <0x00000000>;
+                       clock-frequency = <0>; /* Filled in by U-Boot */
+                       timebase-frequency = <0>; /* Filled in by U-Boot */
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <32768>;
+                       d-cache-size = <32768>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */
+       };
+
+       UIC0: interrupt-controller0 {
+               compatible = "ibm,uic-460gt","ibm,uic";
+               interrupt-controller;
+               cell-index = <0>;
+               dcr-reg = <0x0c0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+       };
+
+       UIC1: interrupt-controller1 {
+               compatible = "ibm,uic-460gt","ibm,uic";
+               interrupt-controller;
+               cell-index = <1>;
+               dcr-reg = <0x0d0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       UIC2: interrupt-controller2 {
+               compatible = "ibm,uic-460gt","ibm,uic";
+               interrupt-controller;
+               cell-index = <2>;
+               dcr-reg = <0x0e0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       UIC3: interrupt-controller3 {
+               compatible = "ibm,uic-460gt","ibm,uic";
+               interrupt-controller;
+               cell-index = <3>;
+               dcr-reg = <0x0f0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       SDR0: sdr {
+               compatible = "ibm,sdr-460gt";
+               dcr-reg = <0x00e 0x002>;
+       };
+
+       CPR0: cpr {
+               compatible = "ibm,cpr-460gt";
+               dcr-reg = <0x00c 0x002>;
+       };
+
+       plb {
+               compatible = "ibm,plb-460gt", "ibm,plb4";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges;
+               clock-frequency = <0>; /* Filled in by U-Boot */
+
+               SDRAM0: sdram {
+                       compatible = "ibm,sdram-460gt", "ibm,sdram-405gp";
+                       dcr-reg = <0x010 0x002>;
+               };
+
+               MAL0: mcmal {
+                       compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
+                       dcr-reg = <0x180 0x062>;
+                       num-tx-chans = <3>;
+                       num-rx-chans = <24>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-parent = <&UIC2>;
+                       interrupts = <  /*TXEOB*/ 0x6 0x4
+                                       /*RXEOB*/ 0x7 0x4
+                                       /*SERR*/  0x3 0x4
+                                       /*TXDE*/  0x4 0x4
+                                       /*RXDE*/  0x5 0x4>;
+                       desc-base-addr-high = <0x8>;
+               };
+
+               POB0: opb {
+                       compatible = "ibm,opb-460gt", "ibm,opb";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
+                       clock-frequency = <0>; /* Filled in by U-Boot */
+
+                       EBC0: ebc {
+                               compatible = "ibm,ebc-460gt", "ibm,ebc";
+                               dcr-reg = <0x012 0x002>;
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               clock-frequency = <0>; /* Filled in by U-Boot */
+                               /* ranges property is supplied by U-Boot */
+                               interrupts = <0x6 0x4>;
+                               interrupt-parent = <&UIC1>;
+                       };
+
+                       UART0: serial@ef600300 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xef600300 0x00000008>;
+                               virtual-reg = <0xef600300>;
+                               clock-frequency = <0>; /* Filled in by U-Boot */
+                               current-speed = <0>; /* Filled in by U-Boot */
+                               interrupt-parent = <&UIC1>;
+                               interrupts = <0x1 0x4>;
+                       };
+
+                       IIC0: i2c@ef600700 {
+                               compatible = "ibm,iic-460gt", "ibm,iic";
+                               reg = <0xef600700 0x00000014>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x2 0x4>;
+                       };
+
+                       IIC1: i2c@ef600800 {
+                               compatible = "ibm,iic-460gt", "ibm,iic";
+                               reg = <0xef600800 0x00000014>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x3 0x4>;
+                       };
+
+                       TAH0: emac-tah@ef601350 {
+                               compatible = "ibm,tah-460gt", "ibm,tah";
+                               reg = <0xef601350 0x00000030>;
+                       };
+
+                       TAH1: emac-tah@ef601450 {
+                               compatible = "ibm,tah-460gt", "ibm,tah";
+                               reg = <0xef601450 0x00000030>;
+                       };
+
+                       EMAC0: ethernet@ef600e00 {
+                               device_type = "network";
+                               compatible = "ibm,emac-460gt", "ibm,emac4sync";
+                               interrupt-parent = <&EMAC0>;
+                               interrupts = <0x0 0x1>;
+                               #interrupt-cells = <1>;
+                               #address-cells = <0>;
+                               #size-cells = <0>;
+                               interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
+                                                /*Wake*/   0x1 &UIC2 0x14 0x4>;
+                               reg = <0xef600e00 0x000000c4>;
+                               local-mac-address = [000000000000]; /* Filled in by U-Boot */
+                               mal-device = <&MAL0>;
+                               mal-tx-channel = <0>;
+                               mal-rx-channel = <0>;
+                               cell-index = <0>;
+                               max-frame-size = <9000>;
+                               rx-fifo-size = <4096>;
+                               tx-fifo-size = <2048>;
+                               phy-mode = "sgmii";
+                               phy-map = <0xffffffff>;
+                               gpcs-address = <0x0000000a>;
+                               tah-device = <&TAH0>;
+                               tah-channel = <0>;
+                               has-inverted-stacr-oc;
+                               has-new-stacr-staopc;
+                       };
+
+                       EMAC1: ethernet@ef600f00 {
+                               device_type = "network";
+                               compatible = "ibm,emac-460gt", "ibm,emac4sync";
+                               interrupt-parent = <&EMAC1>;
+                               interrupts = <0x0 0x1>;
+                               #interrupt-cells = <1>;
+                               #address-cells = <0>;
+                               #size-cells = <0>;
+                               interrupt-map = </*Status*/ 0x0 &UIC2 0x11 0x4
+                                                /*Wake*/   0x1 &UIC2 0x15 0x4>;
+                               reg = <0xef600f00 0x000000c4>;
+                               local-mac-address = [000000000000]; /* Filled in by U-Boot */
+                               mal-device = <&MAL0>;
+                               mal-tx-channel = <1>;
+                               mal-rx-channel = <8>;
+                               cell-index = <1>;
+                               max-frame-size = <9000>;
+                               rx-fifo-size = <4096>;
+                               tx-fifo-size = <2048>;
+                               phy-mode = "sgmii";
+                               phy-map = <0x00000000>;
+                               gpcs-address = <0x0000000b>;
+                               tah-device = <&TAH1>;
+                               tah-channel = <1>;
+                               has-inverted-stacr-oc;
+                               has-new-stacr-staopc;
+                               mdio-device = <&EMAC0>;
+                       };
+
+                       EMAC2: ethernet@ef601100 {
+                               device_type = "network";
+                               compatible = "ibm,emac-460gt", "ibm,emac4sync";
+                               interrupt-parent = <&EMAC2>;
+                               interrupts = <0x0 0x1>;
+                               #interrupt-cells = <1>;
+                               #address-cells = <0>;
+                               #size-cells = <0>;
+                               interrupt-map = </*Status*/ 0x0 &UIC2 0x12 0x4
+                                                /*Wake*/   0x1 &UIC2 0x16 0x4>;
+                               reg = <0xef601100 0x000000c4>;
+                               local-mac-address = [000000000000]; /* Filled in by U-Boot */
+                               mal-device = <&MAL0>;
+                               mal-tx-channel = <2>;
+                               mal-rx-channel = <16>;
+                               cell-index = <2>;
+                               max-frame-size = <9000>;
+                               rx-fifo-size = <4096>;
+                               tx-fifo-size = <2048>;
+                               phy-mode = "sgmii";
+                               phy-map = <0x00000001>;
+                               gpcs-address = <0x0000000C>;
+                               has-inverted-stacr-oc;
+                               has-new-stacr-staopc;
+                               mdio-device = <&EMAC0>;
+                       };
+               };
+       };
+};
index 8b1bb0e41905c422a30697c7ae04b9e008589ffb..6235fca445de43ec0418cc2beb8c0bf91919bff3 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
new file mode 100644 (file)
index 0000000..6ed6083
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * GE Fanuc SBC610 Device Tree Source
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts
+ */
+
+/dts-v1/;
+
+/ {
+       model = "GEF_SBC610";
+       compatible = "gef,sbc610";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       aliases {
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               serial0 = &serial0;
+               serial1 = &serial1;
+               pci0 = &pci0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8641@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <32768>;         // L1, 32K
+                       i-cache-size = <32768>;         // L1, 32K
+                       timebase-frequency = <0>;       // From uboot
+                       bus-frequency = <0>;            // From uboot
+                       clock-frequency = <0>;          // From uboot
+               };
+               PowerPC,8641@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <32768>;         // L1, 32K
+                       i-cache-size = <32768>;         // L1, 32K
+                       timebase-frequency = <0>;       // From uboot
+                       bus-frequency = <0>;            // From uboot
+                       clock-frequency = <0>;          // From uboot
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x40000000>; // set by uboot
+       };
+
+       localbus@fef05000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8641-localbus", "simple-bus";
+               reg = <0xf8005000 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0 0 0xff000000 0x01000000     // 16MB Boot flash
+                         1 0 0xe8000000 0x08000000     // Paged Flash 0
+                         2 0 0xe0000000 0x08000000     // Paged Flash 1
+                         3 0 0xfc100000 0x00020000     // NVRAM
+                         4 0 0xfc000000 0x00008000     // FPGA
+                         5 0 0xfc008000 0x00008000     // AFIX FPGA
+                         6 0 0xfd000000 0x00800000     // IO FPGA (8-bit)
+                         7 0 0xfd800000 0x00800000>;   // IO FPGA (32-bit)
+
+               fpga@4,0 {
+                       compatible = "gef,fpga-regs";
+                       reg = <0x4 0x0 0x40>;
+               };
+               gef_pic: pic@4,4000 {
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
+                       compatible = "gef,fpga-pic";
+                       reg = <0x4 0x4000 0x20>;
+                       interrupts = <0x8
+                                     0x9>;
+                       interrupt-parent = <&mpic>;
+
+               };
+       };
+
+       soc@fef00000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               compatible = "simple-bus";
+               ranges = <0x0 0xfef00000 0x00100000>;
+               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
+               bus-frequency = <0>;
+
+               i2c1: i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <0x2b 0x2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+
+                       eti@6b {
+                               compatible = "dallas,ds1682";
+                               reg = <0x6b>;
+                       };
+               };
+
+               i2c2: i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <0x2b 0x2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                          "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                          "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                          "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                          "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               mdio@24520 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,gianfar-mdio";
+                       reg = <0x24520 0x20>;
+
+                       phy0: ethernet-phy@0 {
+                               interrupt-parent = <&gef_pic>;
+                               interrupts = <0x9 0x4>;
+                               reg = <1>;
+                       };
+                       phy2: ethernet-phy@2 {
+                               interrupt-parent = <&gef_pic>;
+                               interrupts = <0x8 0x4>;
+                               reg = <3>;
+                       };
+               };
+
+               enet0: ethernet@24000 {
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x24000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy0>;
+                       phy-connection-type = "gmii";
+               };
+
+               enet1: ethernet@26000 {
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x26000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy2>;
+                       phy-connection-type = "gmii";
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <0x2a 0x2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <0x1c 0x2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               mpic: pic@40000 {
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               global-utilities@e0000 {
+                       compatible = "fsl,mpc8641-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+       };
+
+       pci0: pcie@fef08000 {
+               compatible = "fsl,mpc8641-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0xfef08000 0x1000>;
+               bus-range = <0x0 0xff>;
+               ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+                         0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <0x18 0x2>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
+                       0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
+                       0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
+                       0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
+               >;
+
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x02000000 0x0 0x80000000
+                                 0x02000000 0x0 0x80000000
+                                 0x0 0x40000000
+
+                                 0x01000000 0x0 0x00000000
+                                 0x01000000 0x0 0x00000000
+                                 0x0 0x00400000>;
+               };
+       };
+};
index 24cf0dba120c89f53933250688783db89cbc627a..f3787a27f6342a2d2a9c17738df5bac9e3a7bd37 100644 (file)
@@ -14,7 +14,7 @@
        #address-cells = <2>;
        #size-cells = <1>;
        model = "amcc,glacier";
-       compatible = "amcc,glacier", "amcc,canyonlands";
+       compatible = "amcc,glacier";
        dcr-parent = <&{/cpus/cpu@0}>;
 
        aliases {
diff --git a/arch/powerpc/boot/dts/mgcoge.dts b/arch/powerpc/boot/dts/mgcoge.dts
new file mode 100644 (file)
index 0000000..633255a
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Device Tree for the MGCOGE plattform from keymile
+ *
+ * Copyright 2008 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.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 the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+       model = "MGCOGE";
+       compatible = "keymile,mgcoge";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       aliases {
+               ethernet0 = &eth0;
+               serial0 = &smc2;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8247@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;
+                       i-cache-line-size = <32>;
+                       d-cache-size = <16384>;
+                       i-cache-size = <16384>;
+                       timebase-frequency = <0>; /* Filled in by U-Boot */
+                       clock-frequency = <0>; /* Filled in by U-Boot */
+                       bus-frequency = <0>; /* Filled in by U-Boot */
+               };
+       };
+
+       localbus@f0010100 {
+               compatible = "fsl,mpc8247-localbus",
+                            "fsl,pq2-localbus",
+                            "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               reg = <0xf0010100 0x40>;
+
+               ranges = <0 0 0xfe000000 0x00400000
+                         5 0 0x50000000 0x20000000
+                       >; /* Filled in by U-Boot */
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0x0 0x400000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       bank-width = <1>;
+                       device-width = <1>;
+                       partition@0 {
+                               label = "u-boot";
+                               reg = <0 0x40000>;
+                       };
+                       partition@40000 {
+                               label = "env";
+                               reg = <0x40000 0x20000>;
+                       };
+                       partition@60000 {
+                               label = "kernel";
+                               reg = <0x60000 0x220000>;
+                       };
+                       partition@280000 {
+                               label = "dtb";
+                               reg = <0x280000 0x20000>;
+                       };
+               };
+
+               flash@5,0 {
+                       compatible = "cfi-flash";
+                       reg = <5 0x0 0x2000000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       bank-width = <2>;
+                       device-width = <2>;
+                       partition@0 {
+                               label = "ramdisk";
+                               reg = <0 0x7a0000>;
+                       };
+                       partition@7a0000 {
+                               label = "user";
+                               reg = <0x7a0000 0x1860000>;
+                       };
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0 0>; /* Filled in by U-Boot */
+       };
+
+       soc@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8247-immr", "fsl,pq2-soc", "simple-bus";
+               ranges = <0x00000000 0xf0000000 0x00053000>;
+
+               // Temporary until code stops depending on it.
+               device_type = "soc";
+
+               cpm@119c0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       #interrupt-cells = <2>;
+                       compatible = "fsl,mpc8247-cpm", "fsl,cpm2",
+                                       "simple-bus";
+                       reg = <0x119c0 0x30>;
+                       ranges;
+
+                       muram {
+                               compatible = "fsl,cpm-muram";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x10000>;
+
+                               data@0 {
+                                       compatible = "fsl,cpm-muram-data";
+                                       reg = <0x80 0x1f80 0x9800 0x800>;
+                               };
+                       };
+
+                       brg@119f0 {
+                               compatible = "fsl,mpc8247-brg",
+                                            "fsl,cpm2-brg",
+                                            "fsl,cpm-brg";
+                               reg = <0x119f0 0x10 0x115f0 0x10>;
+                       };
+
+                       /* Monitor port/SMC2 */
+                       smc2: serial@11a90 {
+                               device_type = "serial";
+                               compatible = "fsl,mpc8247-smc-uart",
+                                            "fsl,cpm2-smc-uart";
+                               reg = <0x11a90 0x20 0x88fc 0x02>;
+                               interrupts = <5 8>;
+                               interrupt-parent = <&PIC>;
+                               fsl,cpm-brg = <2>;
+                               fsl,cpm-command = <0x21200000>;
+                               current-speed = <0>; /* Filled in by U-Boot */
+                       };
+
+                       eth0: ethernet@11a60 {
+                               device_type = "network";
+                               compatible = "fsl,mpc8247-scc-enet",
+                                            "fsl,cpm2-scc-enet";
+                               reg = <0x11a60 0x20 0x8300 0x100 0x11390 1>;
+                               local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */
+                               interrupts = <43 8>;
+                               interrupt-parent = <&PIC>;
+                               linux,network-index = <0>;
+                               fsl,cpm-command = <0xce00000>;
+                               fixed-link = <0 0 10 0 0>;
+                       };
+
+               };
+
+               PIC: interrupt-controller@10c00 {
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <0x10c00 0x80>;
+                       compatible = "fsl,mpc8247-pic", "fsl,pq2-pic";
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/mgsuvd.dts b/arch/powerpc/boot/dts/mgsuvd.dts
new file mode 100644 (file)
index 0000000..e4fc53a
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * MGSUVD Device Tree Source
+ *
+ * Copyright 2008 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.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 the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+       model = "MGSUVD";
+       compatible = "keymile,mgsuvd";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,852@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <16>;
+                       i-cache-line-size = <16>;
+                       d-cache-size = <8192>;
+                       i-cache-size = <8192>;
+                       timebase-frequency = <0>;       /* Filled in by u-boot */
+                       bus-frequency = <0>;            /* Filled in by u-boot */
+                       clock-frequency = <0>;          /* Filled in by u-boot */
+                       interrupts = <15 2>;            /* decrementer interrupt */
+                       interrupt-parent = <&PIC>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <00000000 0x4000000>;  /* Filled in by u-boot */
+       };
+
+       localbus@fff00100 {
+               compatible = "fsl,mpc852-localbus", "fsl,pq1-localbus", "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               reg = <0xfff00100 0x40>;
+
+               ranges = <0 0 0xf0000000 0x01000000>;  /* Filled in by u-boot */
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x1000000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       bank-width = <1>;
+                       device-width = <1>;
+                       partition@0 {
+                               label = "u-boot";
+                               reg = <0 0x80000>;
+                       };
+                       partition@80000 {
+                               label = "env";
+                               reg = <0x80000 0x20000>;
+                       };
+                       partition@a0000 {
+                               label = "kernel";
+                               reg = <0xa0000 0x1e0000>;
+                       };
+                       partition@280000 {
+                               label = "dtb";
+                               reg = <0x280000 0x20000>;
+                       };
+                       partition@2a0000 {
+                               label = "root";
+                               reg = <0x2a0000 0x500000>;
+                       };
+                       partition@7a0000 {
+                               label = "user";
+                               reg = <0x7a0000 0x860000>;
+                       };
+               };
+       };
+
+       soc@fff00000 {
+               compatible = "fsl,mpc852", "fsl,pq1-soc", "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               ranges = <0 0xfff00000 0x00004000>;
+
+               PIC: interrupt-controller@0 {
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       reg = <0 24>;
+                       compatible = "fsl,mpc852-pic", "fsl,pq1-pic";
+               };
+
+               cpm@9c0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc852-cpm", "fsl,cpm1", "simple-bus";
+                       interrupts = <0>;       /* cpm error interrupt */
+                       interrupt-parent = <&CPM_PIC>;
+                       reg = <0x9c0 10>;
+                       ranges;
+
+                       muram@2000 {
+                               compatible = "fsl,cpm-muram";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x2000 0x2000>;
+
+                               data@0 {
+                                       compatible = "fsl,cpm-muram-data";
+                                       reg = <0x800 0x1800>;
+                               };
+                       };
+
+                       brg@9f0 {
+                               compatible = "fsl,mpc852-brg",
+                                            "fsl,cpm1-brg",
+                                            "fsl,cpm-brg";
+                               reg = <0x9f0 0x10>;
+                               clock-frequency = <0>; /* Filled in by u-boot */
+                       };
+
+                       CPM_PIC: interrupt-controller@930 {
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               interrupts = <5 2 0 2>;
+                               interrupt-parent = <&PIC>;
+                               reg = <0x930 0x20>;
+                               compatible = "fsl,cpm1-pic";
+                       };
+
+                       /* MON-1 */
+                       serial@a80 {
+                               device_type = "serial";
+                               compatible = "fsl,cpm1-smc-uart";
+                               reg = <0xa80 0x10 0x3fc0 0x40>;
+                               interrupts = <4>;
+                               interrupt-parent = <&CPM_PIC>;
+                               fsl,cpm-brg = <1>;
+                               fsl,cpm-command = <0x0090>;
+                               current-speed = <0>; /* Filled in by u-boot */
+                       };
+
+                       ethernet@a40 {
+                               device_type = "network";
+                               compatible  = "fsl,mpc866-scc-enet",
+                                             "fsl,cpm1-scc-enet";
+                               reg = <0xa40 0x18 0x3e00 0x100>;
+                               local-mac-address = [ 00 00 00 00 00 00 ];  /* Filled in by u-boot */
+                               interrupts = <28>;
+                               interrupt-parent = <&CPM_PIC>;
+                               fsl,cpm-command = <0x80>;
+                               fixed-link = <0 0 10 0 0>;
+                       };
+               };
+       };
+};
index 1f9036c317b4ab235e9264705ee38fdd1e2c5d14..c2b8dbfab79e6dc1e4fa5f4b365a06d6f103776f 100644 (file)
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0x80008500 0x100>;
+               reg = <0x80008500 0x100         /* internal registers */
+                      0x80008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc5121-pci";
                device_type = "pci";
        };
index 2a94ae0dc8b875c5c080e69c894838ca21545263..747f27676332f1d1fc243da4f36ad19faa23e328 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        #interrupt-cells = <1>;
                        #size-cells = <2>;
                        #address-cells = <3>;
-                       reg = <0xe0008500 0x100>;
+                       reg = <0xe0008500 0x100         /* internal registers */
+                              0xe0008300 0x8>;         /* config space access registers */
                        compatible = "fsl,mpc8349-pci";
                        device_type = "pci";
                };
index f704513fb930b5dd6dcf4270e9592ae8368f271c..7449e54c1a908d46e780aa5815c4ef83b71551bb 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index fbc930410ff6f91f08f9ad16f182906213e2c711..e4cc1768f24165b56446ce5b06a0d4d422f64bbf 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index b157d1885a2884729eeeffe432afb4fe2f9e2d9c..226ff066652ba36e8f5e5c229b643a68c03da49d 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index 700e076ef3f55eb7d47ccde848a1a81ffdaa05c8..5cedf373a1d802e39aba5c21e232b49db2ed71a6 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008600 0x100>;
+               reg = <0xe0008600 0x100         /* internal registers */
+                      0xe0008380 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index cdd3063258ea6a762de3716d49db8a1fe7b748af..81ae1d3e9440ad06be3e14eeb9cb10ce544ae659 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008600 0x100>;
+               reg = <0xe0008600 0x100         /* internal registers */
+                      0xe0008380 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index 783241c0024007f1244b7c933159ae454c3b6e94..04bfde3ea605b2ec64cc528c0e64341e89ff8c33 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008600 0x100>;
+               reg = <0xe0008600 0x100         /* internal registers */
+                      0xe0008380 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index a3b76a709951bce3ffee81bc1b2f19204108eee1..66a12d2631fbd4e39b93e3d6c351ed820703d6c9 100644 (file)
                reg = <0x00000000 0x10000000>;
        };
 
-       bcsr@f8000000 {
-               device_type = "board-control";
-               reg = <0xf8000000 0x8000>;
+       localbus@e0005000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus",
+                            "simple-bus";
+               reg = <0xe0005000 0xd8>;
+               ranges = <0 0 0xfe000000 0x02000000
+                         1 0 0xf8000000 0x00008000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x2000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+
+               bcsr@1,0 {
+                       device_type = "board-control";
+                       reg = <1 0 0x8000>;
+               };
        };
 
        soc8360@e0000000 {
                        dma-channel@0 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index 89c9202f8bd784477e1cce9d1e1ed8867842fd38..decadf3d9e989e935faa898c3d56d5d0676531e1 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        device-width = <1>;
                };
 
+               upm@1,0 {
+                       compatible = "fsl,upm-nand";
+                       reg = <1 0 1>;
+                       fsl,upm-addr-offset = <16>;
+                       fsl,upm-cmd-offset = <8>;
+                       gpios = <&qe_pio_e 18 0>;
+
+                       flash {
+                               compatible = "stm,nand512-a";
+                       };
+               };
+
                display@2,0 {
                        device_type = "display";
                        compatible = "fujitsu,MB86277", "fujitsu,mint";
                #interrupt-cells = <1>;
                device_type = "pci";
                compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci";
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000
                          0x42000000 0 0x80000000 0x80000000 0 0x10000000
                          0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>;
index 432782b6d20ae132ac6644994a9d3cc0dcb2e8f3..0484561bd2c022aab258f40a2ea523144c663339 100644 (file)
                        interrupts = <14 0x8>;
                        interrupt-parent = <&ipic>;
                        dfsrr;
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                               interrupts = <19 0x8>;
+                               interrupt-parent = <&ipic>;
+                       };
                };
 
                i2c@3100 {
                        dma-channel@0 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <0x47 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <0x47 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <0x47 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <0x47 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index ed137aa83d5f01d5c4e50442a6d521a1db84c7ce..53191ba67aaa3a1d2493fb8a251b0f437efff167 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index ed32c8ddafe3e0177b6e415fb2556e4c01d99ad2..67a08d2e2ff254fff684ecfc550cd73e680f0318 100644 (file)
                        interrupts = <14 0x8>;
                        interrupt-parent = <&ipic>;
                        dfsrr;
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                               interrupts = <19 0x8>;
+                               interrupt-parent = <&ipic>;
+                       };
                };
 
                i2c@3100 {
                        dma-channel@0 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index 34a7f2f935e1482d72717d0045fee840a58e69bf..4a09153d160c90967b5b27a0bcfe52cc49561251 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index f4db9ed4a301e1719aa04df4a5d9d2a4f3ff965c..323370a2b5ff6fa38266e593b66110f8230fc33c 100644 (file)
                        interrupts = <14 0x8>;
                        interrupt-parent = <&ipic>;
                        dfsrr;
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                               interrupts = <19 0x8>;
+                               interrupt-parent = <&ipic>;
+                       };
                };
 
                i2c@3100 {
                        dma-channel@0 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index e4d7030d50e558ded5a02f4566d2b5d3cf2a0d08..bbd884ac9dc0e3f84a487f2edb6277416b008cd8 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index 1505d6855eff0eb0e1f5fe7a67c1622b1de6825f..93fdd99901b6e61c9909542ec30338df5b0d8cd8 100644 (file)
@@ -91,6 +91,8 @@
                        rtc@68 {
                                compatible = "dallas,ds3232";
                                reg = <0x68>;
+                               interrupts = <0 0x1>;
+                               interrupt-parent = <&mpic>;
                        };
                };
 
index 584a4f184eb26cddbac0d50c7feb52f406ab7e05..f724d72c7b92db819d2b9229da620938ba6c0104 100644 (file)
                        reg = <0xe4000 0x100>;
                };
 
-               i2s@16000 {
+               ssi@16000 {
                        compatible = "fsl,mpc8610-ssi";
                        cell-index = <0>;
                        reg = <0x16000 0x100>;
                        interrupts = <62 2>;
                        fsl,mode = "i2s-slave";
                        codec-handle = <&cs4270>;
+                       fsl,playback-dma = <&dma00>;
+                       fsl,capture-dma = <&dma01>;
                };
 
                ssi@16100 {
                        reg = <0x21300 0x4>; /* DMA general status register */
                        ranges = <0x0 0x21100 0x200>;
 
-                       dma-channel@0 {
+                       dma00: dma-channel@0 {
                                compatible = "fsl,mpc8610-dma-channel",
-                                       "fsl,eloplus-dma-channel";
+                                       "fsl,ssi-dma-channel";
                                cell-index = <0>;
                                reg = <0x0 0x80>;
                                interrupt-parent = <&mpic>;
                                interrupts = <20 2>;
                        };
-                       dma-channel@1 {
+                       dma01: dma-channel@1 {
                                compatible = "fsl,mpc8610-dma-channel",
-                                       "fsl,eloplus-dma-channel";
+                                       "fsl,ssi-dma-channel";
                                cell-index = <1>;
                                reg = <0x80 0x80>;
                                interrupt-parent = <&mpic>;
index 45f789b56709b410133cb778a4a3c0e736778484..0f941f310e444ae2d209f8195b7f71525cb07ad4 100644 (file)
                        dma-channel@0 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0 0x80>;
+                               cell-index = <0>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x80 0x80>;
+                               cell-index = <1>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x100 0x80>;
+                               cell-index = <2>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
                                reg = <0x180 0x28>;
+                               cell-index = <3>;
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
+               reg = <0xe0008500 0x100         /* internal registers */
+                      0xe0008300 0x8>;         /* config space access registers */
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
index 72d15f075d34638a377b27d62355e1e38adf455c..3b295e8df53f10e5e2f6591b57e9871d21631588 100644 (file)
                        };
 
                        IIC0: i2c@ef600700 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                compatible = "ibm,iic-440epx", "ibm,iic";
                                reg = <0xef600700 0x00000014>;
                                interrupt-parent = <&UIC0>;
                                interrupts = <0x2 0x4>;
+
+                               hwmon@48 {
+                                       compatible = "adi,ad7414";
+                                       reg = <0x48>;
+                               };
                        };
 
                        IIC1: i2c@ef600800 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                compatible = "ibm,iic-440epx", "ibm,iic";
                                reg = <0xef600800 0x00000014>;
                                interrupt-parent = <&UIC0>;
index e39422aa0d855e794658c65a79bdab132ecdc3f1..1fa3cb4c4ebb7fd352c3a73c6cdca89623a6df38 100644 (file)
@@ -15,7 +15,7 @@
        #address-cells = <2>;
        #size-cells = <1>;
        model = "amcc,yosemite";
-       compatible = "amcc,yosemite","amcc,bamboo";
+       compatible = "amcc,yosemite";
        dcr-parent = <&{/cpus/cpu@0}>;
 
        aliases {
index 7454aa4cc20c6a76068c4c2a54e0bf910a2becbd..1567a0c0f05c6639a96ce4947dfb9bdf23eda8fc 100644 (file)
@@ -27,7 +27,8 @@ int parse_elf64(void *hdr, struct elf_info *info)
              elf64->e_ident[EI_MAG3]  == ELFMAG3       &&
              elf64->e_ident[EI_CLASS] == ELFCLASS64    &&
              elf64->e_ident[EI_DATA]  == ELFDATA2MSB   &&
-             elf64->e_type            == ET_EXEC       &&
+             (elf64->e_type            == ET_EXEC ||
+              elf64->e_type            == ET_DYN)      &&
              elf64->e_machine         == EM_PPC64))
                return 0;
 
@@ -58,7 +59,8 @@ int parse_elf32(void *hdr, struct elf_info *info)
              elf32->e_ident[EI_MAG3]  == ELFMAG3       &&
              elf32->e_ident[EI_CLASS] == ELFCLASS32    &&
              elf32->e_ident[EI_DATA]  == ELFDATA2MSB   &&
-             elf32->e_type            == ET_EXEC       &&
+             (elf32->e_type            == ET_EXEC ||
+              elf32->e_type            == ET_DYN)      &&
              elf32->e_machine         == EM_PPC))
                return 0;
 
index 82f9c6a8287b8a7793efdd8f58118f45d7020d34..6c42acfa21ec61282dd53f67dbb70c795c5cc649 100644 (file)
@@ -3,12 +3,6 @@
 # This is not a complete Makefile of itself.  Instead, it is designed to
 # be easily embeddable into other systems of Makefiles.
 #
-LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
 LIBFDT_INCLUDES = fdt.h libfdt.h
-LIBFDT_EXTRA = libfdt_internal.h
-LIBFDT_LIB = libfdt/libfdt.a
-
+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
 LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
-
-$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
-
index 586a36136db215fbffb450cfa475403d6755c311..2acaec5923aea4fc5cb3f8360a1e6105f7c99897 100644 (file)
@@ -63,7 +63,7 @@ int fdt_check_header(const void *fdt)
                        return -FDT_ERR_BADVERSION;
                if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
                        return -FDT_ERR_BADVERSION;
-       } else if (fdt_magic(fdt) == SW_MAGIC) {
+       } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
                /* Unfinished sequential-write blob */
                if (fdt_size_dt_struct(fdt) == 0)
                        return -FDT_ERR_BADSTATE;
@@ -76,7 +76,7 @@ int fdt_check_header(const void *fdt)
 
 const void *fdt_offset_ptr(const void *fdt, int offset, int len)
 {
-       const void *p;
+       const char *p;
 
        if (fdt_version(fdt) >= 0x11)
                if (((offset + len) < offset)
@@ -124,11 +124,59 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
        }
 
        if (nextoffset)
-               *nextoffset = ALIGN(offset, FDT_TAGSIZE);
+               *nextoffset = FDT_TAGALIGN(offset);
 
        return tag;
 }
 
+int _fdt_check_node_offset(const void *fdt, int offset)
+{
+       if ((offset < 0) || (offset % FDT_TAGSIZE)
+           || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
+               return -FDT_ERR_BADOFFSET;
+
+       return offset;
+}
+
+int fdt_next_node(const void *fdt, int offset, int *depth)
+{
+       int nextoffset = 0;
+       uint32_t tag;
+
+       if (offset >= 0)
+               if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
+                       return nextoffset;
+
+       do {
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+               switch (tag) {
+               case FDT_PROP:
+               case FDT_NOP:
+                       break;
+
+               case FDT_BEGIN_NODE:
+                       if (depth)
+                               (*depth)++;
+                       break;
+
+               case FDT_END_NODE:
+                       if (depth)
+                               (*depth)--;
+                       break;
+
+               case FDT_END:
+                       return -FDT_ERR_NOTFOUND;
+
+               default:
+                       return -FDT_ERR_BADSTRUCTURE;
+               }
+       } while (tag != FDT_BEGIN_NODE);
+
+       return offset;
+}
+
 const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
 {
        int len = strlen(s) + 1;
@@ -136,17 +184,14 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
        const char *p;
 
        for (p = strtab; p <= last; p++)
-               if (memeq(p, s, len))
+               if (memcmp(p, s, len) == 0)
                        return p;
        return NULL;
 }
 
 int fdt_move(const void *fdt, void *buf, int bufsize)
 {
-       int err = fdt_check_header(fdt);
-
-       if (err)
-               return err;
+       FDT_CHECK_HEADER(fdt);
 
        if (fdt_totalsize(fdt) > bufsize)
                return -FDT_ERR_NOSPACE;
index 12a37d59f96eba267235cf06962f7ccc7a6c2259..129b532bcc1a8f9752caf666a0b1e45956e926eb 100644 (file)
 
 #include "libfdt_internal.h"
 
-#define CHECK_HEADER(fdt) \
-       { \
-               int err; \
-               if ((err = fdt_check_header(fdt)) != 0) \
-                       return err; \
-       }
-
-static int nodename_eq(const void *fdt, int offset,
-                      const char *s, int len)
+static int _fdt_nodename_eq(const void *fdt, int offset,
+                           const char *s, int len)
 {
-       const char *p = fdt_offset_ptr(fdt, offset, len+1);
+       const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
 
        if (! p)
                /* short match */
@@ -84,12 +77,12 @@ static int nodename_eq(const void *fdt, int offset,
 
 const char *fdt_string(const void *fdt, int stroffset)
 {
-       return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+       return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
-       CHECK_HEADER(fdt);
+       FDT_CHECK_HEADER(fdt);
        *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
        *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
        return 0;
@@ -104,50 +97,24 @@ int fdt_num_mem_rsv(const void *fdt)
        return i;
 }
 
-int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+int fdt_subnode_offset_namelen(const void *fdt, int offset,
                               const char *name, int namelen)
 {
-       int level = 0;
-       uint32_t tag;
-       int offset, nextoffset;
-
-       CHECK_HEADER(fdt);
-
-       tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
-       if (tag != FDT_BEGIN_NODE)
-               return -FDT_ERR_BADOFFSET;
-
-       do {
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset);
-
-               switch (tag) {
-               case FDT_END:
-                       return -FDT_ERR_TRUNCATED;
-
-               case FDT_BEGIN_NODE:
-                       level++;
-                       if (level != 1)
-                               continue;
-                       if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
-                               /* Found it! */
-                               return offset;
-                       break;
-
-               case FDT_END_NODE:
-                       level--;
-                       break;
+       int depth;
 
-               case FDT_PROP:
-               case FDT_NOP:
-                       break;
+       FDT_CHECK_HEADER(fdt);
 
-               default:
-                       return -FDT_ERR_BADSTRUCTURE;
-               }
-       } while (level >= 0);
+       for (depth = 0;
+            offset >= 0;
+            offset = fdt_next_node(fdt, offset, &depth)) {
+               if (depth < 0)
+                       return -FDT_ERR_NOTFOUND;
+               else if ((depth == 1)
+                        && _fdt_nodename_eq(fdt, offset, name, namelen))
+                       return offset;
+       }
 
-       return -FDT_ERR_NOTFOUND;
+       return offset; /* error */
 }
 
 int fdt_subnode_offset(const void *fdt, int parentoffset,
@@ -162,7 +129,7 @@ int fdt_path_offset(const void *fdt, const char *path)
        const char *p = path;
        int offset = 0;
 
-       CHECK_HEADER(fdt);
+       FDT_CHECK_HEADER(fdt);
 
        if (*path != '/')
                return -FDT_ERR_BADPATH;
@@ -190,16 +157,12 @@ int fdt_path_offset(const void *fdt, const char *path)
 
 const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
 {
-       const struct fdt_node_header *nh;
+       const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
        int err;
 
-       if ((err = fdt_check_header(fdt)) != 0)
-               goto fail;
-
-       err = -FDT_ERR_BADOFFSET;
-       nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
-       if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
-               goto fail;
+       if (((err = fdt_check_header(fdt)) != 0)
+           || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+                       goto fail;
 
        if (len)
                *len = strlen(nh->name);
@@ -222,17 +185,11 @@ const struct fdt_property *fdt_get_property(const void *fdt,
        int offset, nextoffset;
        int err;
 
-       if ((err = fdt_check_header(fdt)) != 0)
-               goto fail;
-
-       err = -FDT_ERR_BADOFFSET;
-       if (nodeoffset % FDT_TAGSIZE)
-               goto fail;
-
-       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
-       if (tag != FDT_BEGIN_NODE)
-               goto fail;
+       if (((err = fdt_check_header(fdt)) != 0)
+           || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+                       goto fail;
 
+       nextoffset = err;
        do {
                offset = nextoffset;
 
@@ -253,7 +210,7 @@ const struct fdt_property *fdt_get_property(const void *fdt,
                        if (! prop)
                                goto fail;
                        namestroff = fdt32_to_cpu(prop->nameoff);
-                       if (streq(fdt_string(fdt, namestroff), name)) {
+                       if (strcmp(fdt_string(fdt, namestroff), name) == 0) {
                                /* Found it! */
                                int len = fdt32_to_cpu(prop->len);
                                prop = fdt_offset_ptr(fdt, offset,
@@ -307,115 +264,91 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
 
 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
 {
-       uint32_t tag;
-       int p = 0, overflow = 0;
-       int offset, nextoffset, namelen;
+       int pdepth = 0, p = 0;
+       int offset, depth, namelen;
        const char *name;
 
-       CHECK_HEADER(fdt);
-
-       tag = fdt_next_tag(fdt, 0, &nextoffset);
-       if (tag != FDT_BEGIN_NODE)
-               return -FDT_ERR_BADSTRUCTURE;
+       FDT_CHECK_HEADER(fdt);
 
        if (buflen < 2)
                return -FDT_ERR_NOSPACE;
-       buf[0] = '/';
-       p = 1;
 
-       while (nextoffset <= nodeoffset) {
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset);
-               switch (tag) {
-               case FDT_END:
-                       return -FDT_ERR_BADOFFSET;
+       for (offset = 0, depth = 0;
+            (offset >= 0) && (offset <= nodeoffset);
+            offset = fdt_next_node(fdt, offset, &depth)) {
+               if (pdepth < depth)
+                       continue; /* overflowed buffer */
 
-               case FDT_BEGIN_NODE:
-                       name = fdt_get_name(fdt, offset, &namelen);
-                       if (!name)
-                               return namelen;
-                       if (overflow || ((p + namelen + 1) > buflen)) {
-                               overflow++;
-                               break;
-                       }
+               while (pdepth > depth) {
+                       do {
+                               p--;
+                       } while (buf[p-1] != '/');
+                       pdepth--;
+               }
+
+               name = fdt_get_name(fdt, offset, &namelen);
+               if (!name)
+                       return namelen;
+               if ((p + namelen + 1) <= buflen) {
                        memcpy(buf + p, name, namelen);
                        p += namelen;
                        buf[p++] = '/';
-                       break;
-
-               case FDT_END_NODE:
-                       if (overflow) {
-                               overflow--;
-                               break;
-                       }
-                       do {
-                               p--;
-                       } while  (buf[p-1] != '/');
-                       break;
+                       pdepth++;
+               }
 
-               case FDT_PROP:
-               case FDT_NOP:
-                       break;
+               if (offset == nodeoffset) {
+                       if (pdepth < (depth + 1))
+                               return -FDT_ERR_NOSPACE;
 
-               default:
-                       return -FDT_ERR_BADSTRUCTURE;
+                       if (p > 1) /* special case so that root path is "/", not "" */
+                               p--;
+                       buf[p] = '\0';
+                       return p;
                }
        }
 
-       if (overflow)
-               return -FDT_ERR_NOSPACE;
+       if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+               return -FDT_ERR_BADOFFSET;
+       else if (offset == -FDT_ERR_BADOFFSET)
+               return -FDT_ERR_BADSTRUCTURE;
 
-       if (p > 1) /* special case so that root path is "/", not "" */
-               p--;
-       buf[p] = '\0';
-       return p;
+       return offset; /* error from fdt_next_node() */
 }
 
 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
                                 int supernodedepth, int *nodedepth)
 {
-       int level = -1;
-       uint32_t tag;
-       int offset, nextoffset = 0;
+       int offset, depth;
        int supernodeoffset = -FDT_ERR_INTERNAL;
 
-       CHECK_HEADER(fdt);
+       FDT_CHECK_HEADER(fdt);
 
        if (supernodedepth < 0)
                return -FDT_ERR_NOTFOUND;
 
-       do {
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset);
-               switch (tag) {
-               case FDT_END:
-                       return -FDT_ERR_BADOFFSET;
-
-               case FDT_BEGIN_NODE:
-                       level++;
-                       if (level == supernodedepth)
-                               supernodeoffset = offset;
-                       break;
-
-               case FDT_END_NODE:
-                       level--;
-                       break;
+       for (offset = 0, depth = 0;
+            (offset >= 0) && (offset <= nodeoffset);
+            offset = fdt_next_node(fdt, offset, &depth)) {
+               if (depth == supernodedepth)
+                       supernodeoffset = offset;
 
-               case FDT_PROP:
-               case FDT_NOP:
-                       break;
+               if (offset == nodeoffset) {
+                       if (nodedepth)
+                               *nodedepth = depth;
 
-               default:
-                       return -FDT_ERR_BADSTRUCTURE;
+                       if (supernodedepth > depth)
+                               return -FDT_ERR_NOTFOUND;
+                       else
+                               return supernodeoffset;
                }
-       } while (offset < nodeoffset);
+       }
 
-       if (nodedepth)
-               *nodedepth = level;
+       if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+               return -FDT_ERR_BADOFFSET;
+       else if (offset == -FDT_ERR_BADOFFSET)
+               return -FDT_ERR_BADSTRUCTURE;
 
-       if (supernodedepth > level)
-               return -FDT_ERR_NOTFOUND;
-       return supernodeoffset;
+       return offset; /* error from fdt_next_node() */
 }
 
 int fdt_node_depth(const void *fdt, int nodeoffset)
@@ -443,51 +376,27 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
                                  const char *propname,
                                  const void *propval, int proplen)
 {
-       uint32_t tag;
-       int offset, nextoffset;
+       int offset;
        const void *val;
        int len;
 
-       CHECK_HEADER(fdt);
-
-       if (startoffset >= 0) {
-               tag = fdt_next_tag(fdt, startoffset, &nextoffset);
-               if (tag != FDT_BEGIN_NODE)
-                       return -FDT_ERR_BADOFFSET;
-       } else {
-               nextoffset = 0;
-       }
+       FDT_CHECK_HEADER(fdt);
 
        /* FIXME: The algorithm here is pretty horrible: we scan each
         * property of a node in fdt_getprop(), then if that didn't
         * find what we want, we scan over them again making our way
         * to the next node.  Still it's the easiest to implement
         * approach; performance can come later. */
-       do {
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset);
-
-               switch (tag) {
-               case FDT_BEGIN_NODE:
-                       val = fdt_getprop(fdt, offset, propname, &len);
-                       if (val
-                           && (len == proplen)
-                           && (memcmp(val, propval, len) == 0))
-                               return offset;
-                       break;
-
-               case FDT_PROP:
-               case FDT_END:
-               case FDT_END_NODE:
-               case FDT_NOP:
-                       break;
-
-               default:
-                       return -FDT_ERR_BADSTRUCTURE;
-               }
-       } while (tag != FDT_END);
+       for (offset = fdt_next_node(fdt, startoffset, NULL);
+            offset >= 0;
+            offset = fdt_next_node(fdt, offset, NULL)) {
+               val = fdt_getprop(fdt, offset, propname, &len);
+               if (val && (len == proplen)
+                   && (memcmp(val, propval, len) == 0))
+                       return offset;
+       }
 
-       return -FDT_ERR_NOTFOUND;
+       return offset; /* error from fdt_next_node() */
 }
 
 int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
@@ -499,10 +408,10 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
                                             &phandle, sizeof(phandle));
 }
 
-int _stringlist_contains(const void *strlist, int listlen, const char *str)
+int _stringlist_contains(const char *strlist, int listlen, const char *str)
 {
        int len = strlen(str);
-       const void *p;
+       const char *p;
 
        while (listlen >= len) {
                if (memcmp(str, strlist, len+1) == 0)
@@ -534,50 +443,24 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
 int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
                                  const char *compatible)
 {
-       uint32_t tag;
-       int offset, nextoffset;
-       int err;
-
-       CHECK_HEADER(fdt);
+       int offset, err;
 
-       if (startoffset >= 0) {
-               tag = fdt_next_tag(fdt, startoffset, &nextoffset);
-               if (tag != FDT_BEGIN_NODE)
-                       return -FDT_ERR_BADOFFSET;
-       } else {
-               nextoffset = 0;
-       }
+       FDT_CHECK_HEADER(fdt);
 
        /* FIXME: The algorithm here is pretty horrible: we scan each
         * property of a node in fdt_node_check_compatible(), then if
         * that didn't find what we want, we scan over them again
         * making our way to the next node.  Still it's the easiest to
         * implement approach; performance can come later. */
-       do {
-               offset = nextoffset;
-               tag = fdt_next_tag(fdt, offset, &nextoffset);
-
-               switch (tag) {
-               case FDT_BEGIN_NODE:
-                       err = fdt_node_check_compatible(fdt, offset,
-                                                       compatible);
-                       if ((err < 0)
-                           && (err != -FDT_ERR_NOTFOUND))
-                               return err;
-                       else if (err == 0)
-                               return offset;
-                       break;
-
-               case FDT_PROP:
-               case FDT_END:
-               case FDT_END_NODE:
-               case FDT_NOP:
-                       break;
-
-               default:
-                       return -FDT_ERR_BADSTRUCTURE;
-               }
-       } while (tag != FDT_END);
+       for (offset = fdt_next_node(fdt, startoffset, NULL);
+            offset >= 0;
+            offset = fdt_next_node(fdt, offset, NULL)) {
+               err = fdt_node_check_compatible(fdt, offset, compatible);
+               if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
+                       return err;
+               else if (err == 0)
+                       return offset;
+       }
 
-       return -FDT_ERR_NOTFOUND;
+       return offset; /* error from fdt_next_node() */
 }
index 6673f8ec962ad39510e25a36a56a3fd5cd5650d8..8e7ec4cb7bcdc91abe0e4b77e5f2ffdd0b5d0a00 100644 (file)
 
 #include "libfdt_internal.h"
 
-static int _blocks_misordered(const void *fdt,
+static int _fdt_blocks_misordered(const void *fdt,
                              int mem_rsv_size, int struct_size)
 {
-       return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
+       return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
                || (fdt_off_dt_struct(fdt) <
                    (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
                || (fdt_off_dt_strings(fdt) <
@@ -67,16 +67,14 @@ static int _blocks_misordered(const void *fdt,
                    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
 }
 
-static int rw_check_header(void *fdt)
+static int _fdt_rw_check_header(void *fdt)
 {
-       int err;
+       FDT_CHECK_HEADER(fdt);
 
-       if ((err = fdt_check_header(fdt)))
-               return err;
        if (fdt_version(fdt) < 17)
                return -FDT_ERR_BADVERSION;
-       if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
-                              fdt_size_dt_struct(fdt)))
+       if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+                                  fdt_size_dt_struct(fdt)))
                return -FDT_ERR_BADLAYOUT;
        if (fdt_version(fdt) > 17)
                fdt_set_version(fdt, 17);
@@ -84,36 +82,37 @@ static int rw_check_header(void *fdt)
        return 0;
 }
 
-#define RW_CHECK_HEADER(fdt) \
+#define FDT_RW_CHECK_HEADER(fdt) \
        { \
                int err; \
-               if ((err = rw_check_header(fdt)) != 0) \
+               if ((err = _fdt_rw_check_header(fdt)) != 0) \
                        return err; \
        }
 
-static inline int _blob_data_size(void *fdt)
+static inline int _fdt_data_size(void *fdt)
 {
        return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 }
 
-static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
+static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
 {
-       void *end = fdt + _blob_data_size(fdt);
+       char *p = splicepoint;
+       char *end = (char *)fdt + _fdt_data_size(fdt);
 
        if (((p + oldlen) < p) || ((p + oldlen) > end))
                return -FDT_ERR_BADOFFSET;
-       if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
+       if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
                return -FDT_ERR_NOSPACE;
        memmove(p + newlen, p + oldlen, end - p - oldlen);
        return 0;
 }
 
-static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
-                               int oldn, int newn)
+static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+                              int oldn, int newn)
 {
        int delta = (newn - oldn) * sizeof(*p);
        int err;
-       err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+       err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
        if (err)
                return err;
        fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
@@ -121,13 +120,13 @@ static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
        return 0;
 }
 
-static int _blob_splice_struct(void *fdt, void *p,
-                              int oldlen, int newlen)
+static int _fdt_splice_struct(void *fdt, void *p,
+                             int oldlen, int newlen)
 {
        int delta = newlen - oldlen;
        int err;
 
-       if ((err = _blob_splice(fdt, p, oldlen, newlen)))
+       if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
                return err;
 
        fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
@@ -135,19 +134,20 @@ static int _blob_splice_struct(void *fdt, void *p,
        return 0;
 }
 
-static int _blob_splice_string(void *fdt, int newlen)
+static int _fdt_splice_string(void *fdt, int newlen)
 {
-       void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+       void *p = (char *)fdt
+               + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
        int err;
 
-       if ((err = _blob_splice(fdt, p, 0, newlen)))
+       if ((err = _fdt_splice(fdt, p, 0, newlen)))
                return err;
 
        fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
        return 0;
 }
 
-static int _find_add_string(void *fdt, const char *s)
+static int _fdt_find_add_string(void *fdt, const char *s)
 {
        char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
        const char *p;
@@ -161,7 +161,7 @@ static int _find_add_string(void *fdt, const char *s)
                return (p - strtab);
 
        new = strtab + fdt_size_dt_strings(fdt);
-       err = _blob_splice_string(fdt, len);
+       err = _fdt_splice_string(fdt, len);
        if (err)
                return err;
 
@@ -174,11 +174,10 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
        struct fdt_reserve_entry *re;
        int err;
 
-       if ((err = rw_check_header(fdt)))
-               return err;
+       FDT_RW_CHECK_HEADER(fdt);
 
        re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
-       err = _blob_splice_mem_rsv(fdt, re, 0, 1);
+       err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
        if (err)
                return err;
 
@@ -192,19 +191,19 @@ int fdt_del_mem_rsv(void *fdt, int n)
        struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
        int err;
 
-       if ((err = rw_check_header(fdt)))
-               return err;
+       FDT_RW_CHECK_HEADER(fdt);
+
        if (n >= fdt_num_mem_rsv(fdt))
                return -FDT_ERR_NOTFOUND;
 
-       err = _blob_splice_mem_rsv(fdt, re, 1, 0);
+       err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
        if (err)
                return err;
        return 0;
 }
 
-static int _resize_property(void *fdt, int nodeoffset, const char *name, int len,
-                           struct fdt_property **prop)
+static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
+                               int len, struct fdt_property **prop)
 {
        int oldlen;
        int err;
@@ -213,36 +212,33 @@ static int _resize_property(void *fdt, int nodeoffset, const char *name, int len
        if (! (*prop))
                return oldlen;
 
-       if ((err = _blob_splice_struct(fdt, (*prop)->data,
-                                      ALIGN(oldlen, FDT_TAGSIZE),
-                                      ALIGN(len, FDT_TAGSIZE))))
+       if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
+                                     FDT_TAGALIGN(len))))
                return err;
 
        (*prop)->len = cpu_to_fdt32(len);
        return 0;
 }
 
-static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
-                        struct fdt_property **prop)
+static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
+                            int len, struct fdt_property **prop)
 {
-       uint32_t tag;
        int proplen;
        int nextoffset;
        int namestroff;
        int err;
 
-       tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
-       if (tag != FDT_BEGIN_NODE)
-               return -FDT_ERR_BADOFFSET;
+       if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+               return nextoffset;
 
-       namestroff = _find_add_string(fdt, name);
+       namestroff = _fdt_find_add_string(fdt, name);
        if (namestroff < 0)
                return namestroff;
 
        *prop = _fdt_offset_ptr_w(fdt, nextoffset);
-       proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE);
+       proplen = sizeof(**prop) + FDT_TAGALIGN(len);
 
-       err = _blob_splice_struct(fdt, *prop, 0, proplen);
+       err = _fdt_splice_struct(fdt, *prop, 0, proplen);
        if (err)
                return err;
 
@@ -252,18 +248,40 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
        return 0;
 }
 
+int fdt_set_name(void *fdt, int nodeoffset, const char *name)
+{
+       char *namep;
+       int oldlen, newlen;
+       int err;
+
+       FDT_RW_CHECK_HEADER(fdt);
+
+       namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
+       if (!namep)
+               return oldlen;
+
+       newlen = strlen(name);
+
+       err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
+                                FDT_TAGALIGN(newlen+1));
+       if (err)
+               return err;
+
+       memcpy(namep, name, newlen+1);
+       return 0;
+}
+
 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
                const void *val, int len)
 {
        struct fdt_property *prop;
        int err;
 
-       if ((err = rw_check_header(fdt)))
-               return err;
+       FDT_RW_CHECK_HEADER(fdt);
 
-       err = _resize_property(fdt, nodeoffset, name, len, &prop);
+       err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
        if (err == -FDT_ERR_NOTFOUND)
-               err = _add_property(fdt, nodeoffset, name, len, &prop);
+               err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
        if (err)
                return err;
 
@@ -276,14 +294,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
        struct fdt_property *prop;
        int len, proplen;
 
-       RW_CHECK_HEADER(fdt);
+       FDT_RW_CHECK_HEADER(fdt);
 
        prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
        if (! prop)
                return len;
 
-       proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE);
-       return _blob_splice_struct(fdt, prop, proplen, 0);
+       proplen = sizeof(*prop) + FDT_TAGALIGN(len);
+       return _fdt_splice_struct(fdt, prop, proplen, 0);
 }
 
 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
@@ -296,7 +314,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
        uint32_t tag;
        uint32_t *endtag;
 
-       RW_CHECK_HEADER(fdt);
+       FDT_RW_CHECK_HEADER(fdt);
 
        offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
        if (offset >= 0)
@@ -309,19 +327,19 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
        do {
                offset = nextoffset;
                tag = fdt_next_tag(fdt, offset, &nextoffset);
-       } while (tag == FDT_PROP);
+       } while ((tag == FDT_PROP) || (tag == FDT_NOP));
 
        nh = _fdt_offset_ptr_w(fdt, offset);
-       nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE;
+       nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
 
-       err = _blob_splice_struct(fdt, nh, 0, nodelen);
+       err = _fdt_splice_struct(fdt, nh, 0, nodelen);
        if (err)
                return err;
 
        nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
-       memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE));
+       memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
        memcpy(nh->name, name, namelen);
-       endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE);
+       endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
        *endtag = cpu_to_fdt32(FDT_END_NODE);
 
        return offset;
@@ -336,36 +354,36 @@ int fdt_del_node(void *fdt, int nodeoffset)
 {
        int endoffset;
 
-       RW_CHECK_HEADER(fdt);
+       FDT_RW_CHECK_HEADER(fdt);
 
        endoffset = _fdt_node_end_offset(fdt, nodeoffset);
        if (endoffset < 0)
                return endoffset;
 
-       return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
-                                  endoffset - nodeoffset, 0);
+       return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
+                                 endoffset - nodeoffset, 0);
 }
 
-static void _packblocks(const void *fdt, void *buf,
-                      int mem_rsv_size, int struct_size)
+static void _fdt_packblocks(const char *old, char *new,
+                           int mem_rsv_size, int struct_size)
 {
        int mem_rsv_off, struct_off, strings_off;
 
-       mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8);
+       mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
        struct_off = mem_rsv_off + mem_rsv_size;
        strings_off = struct_off + struct_size;
 
-       memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
-       fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
+       memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
+       fdt_set_off_mem_rsvmap(new, mem_rsv_off);
 
-       memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
-       fdt_set_off_dt_struct(buf, struct_off);
-       fdt_set_size_dt_struct(buf, struct_size);
+       memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
+       fdt_set_off_dt_struct(new, struct_off);
+       fdt_set_size_dt_struct(new, struct_size);
 
-       memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
-               fdt_size_dt_strings(fdt));
-       fdt_set_off_dt_strings(buf, strings_off);
-       fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
+       memmove(new + strings_off, old + fdt_off_dt_strings(old),
+               fdt_size_dt_strings(old));
+       fdt_set_off_dt_strings(new, strings_off);
+       fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
 }
 
 int fdt_open_into(const void *fdt, void *buf, int bufsize)
@@ -373,11 +391,11 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
        int err;
        int mem_rsv_size, struct_size;
        int newsize;
-       void *tmp;
+       const char *fdtstart = fdt;
+       const char *fdtend = fdtstart + fdt_totalsize(fdt);
+       char *tmp;
 
-       err = fdt_check_header(fdt);
-       if (err)
-               return err;
+       FDT_CHECK_HEADER(fdt);
 
        mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
                * sizeof(struct fdt_reserve_entry);
@@ -390,7 +408,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
                        ;
        }
 
-       if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+       if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
                /* no further work necessary */
                err = fdt_move(fdt, buf, bufsize);
                if (err)
@@ -402,22 +420,23 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
        }
 
        /* Need to reorder */
-       newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+       newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
                + struct_size + fdt_size_dt_strings(fdt);
 
        if (bufsize < newsize)
                return -FDT_ERR_NOSPACE;
 
-       if (((buf + newsize) <= fdt)
-           || (buf >= (fdt + fdt_totalsize(fdt)))) {
-               tmp = buf;
-       } else {
-               tmp = (void *)fdt + fdt_totalsize(fdt);
-               if ((tmp + newsize) > (buf + bufsize))
+       /* First attempt to build converted tree at beginning of buffer */
+       tmp = buf;
+       /* But if that overlaps with the old tree... */
+       if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
+               /* Try right after the old tree instead */
+               tmp = (char *)(uintptr_t)fdtend;
+               if ((tmp + newsize) > ((char *)buf + bufsize))
                        return -FDT_ERR_NOSPACE;
        }
 
-       _packblocks(fdt, tmp, mem_rsv_size, struct_size);
+       _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
        memmove(buf, tmp, newsize);
 
        fdt_set_magic(buf, FDT_MAGIC);
@@ -432,16 +451,13 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
 int fdt_pack(void *fdt)
 {
        int mem_rsv_size;
-       int err;
 
-       err = rw_check_header(fdt);
-       if (err)
-               return err;
+       FDT_RW_CHECK_HEADER(fdt);
 
        mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
                * sizeof(struct fdt_reserve_entry);
-       _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
-       fdt_set_totalsize(fdt, _blob_data_size(fdt));
+       _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+       fdt_set_totalsize(fdt, _fdt_data_size(fdt));
 
        return 0;
 }
index f9d32ef5360ab7acc84f23df066621b18f01f646..e6c3ceee8c58c56beee386e6ed730e32c4ff646b 100644 (file)
 
 #include "libfdt_internal.h"
 
-struct errtabent {
+struct fdt_errtabent {
        const char *str;
 };
 
-#define ERRTABENT(val) \
+#define FDT_ERRTABENT(val) \
        [(val)] = { .str = #val, }
 
-static struct errtabent errtable[] = {
-       ERRTABENT(FDT_ERR_NOTFOUND),
-       ERRTABENT(FDT_ERR_EXISTS),
-       ERRTABENT(FDT_ERR_NOSPACE),
+static struct fdt_errtabent fdt_errtable[] = {
+       FDT_ERRTABENT(FDT_ERR_NOTFOUND),
+       FDT_ERRTABENT(FDT_ERR_EXISTS),
+       FDT_ERRTABENT(FDT_ERR_NOSPACE),
 
-       ERRTABENT(FDT_ERR_BADOFFSET),
-       ERRTABENT(FDT_ERR_BADPATH),
-       ERRTABENT(FDT_ERR_BADSTATE),
+       FDT_ERRTABENT(FDT_ERR_BADOFFSET),
+       FDT_ERRTABENT(FDT_ERR_BADPATH),
+       FDT_ERRTABENT(FDT_ERR_BADSTATE),
 
-       ERRTABENT(FDT_ERR_TRUNCATED),
-       ERRTABENT(FDT_ERR_BADMAGIC),
-       ERRTABENT(FDT_ERR_BADVERSION),
-       ERRTABENT(FDT_ERR_BADSTRUCTURE),
-       ERRTABENT(FDT_ERR_BADLAYOUT),
+       FDT_ERRTABENT(FDT_ERR_TRUNCATED),
+       FDT_ERRTABENT(FDT_ERR_BADMAGIC),
+       FDT_ERRTABENT(FDT_ERR_BADVERSION),
+       FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
+       FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
 };
-#define ERRTABSIZE     (sizeof(errtable) / sizeof(errtable[0]))
+#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
 
 const char *fdt_strerror(int errval)
 {
@@ -85,8 +85,8 @@ const char *fdt_strerror(int errval)
                return "<valid offset/length>";
        else if (errval == 0)
                return "<no error>";
-       else if (errval > -ERRTABSIZE) {
-               const char *s = errtable[-errval].str;
+       else if (errval > -FDT_ERRTABSIZE) {
+               const char *s = fdt_errtable[-errval].str;
 
                if (s)
                        return s;
index dda2de34b2e0a968463cf808b669b37e226620df..698329e0ccaf8f94d2e333b277a78ab3dcff9adc 100644 (file)
 
 #include "libfdt_internal.h"
 
-static int check_header_sw(void *fdt)
+static int _fdt_sw_check_header(void *fdt)
 {
-       if (fdt_magic(fdt) != SW_MAGIC)
+       if (fdt_magic(fdt) != FDT_SW_MAGIC)
                return -FDT_ERR_BADMAGIC;
+       /* FIXME: should check more details about the header state */
        return 0;
 }
 
-static void *grab_space(void *fdt, int len)
+#define FDT_SW_CHECK_HEADER(fdt) \
+       { \
+               int err; \
+               if ((err = _fdt_sw_check_header(fdt)) != 0) \
+                       return err; \
+       }
+
+static void *_fdt_grab_space(void *fdt, int len)
 {
        int offset = fdt_size_dt_struct(fdt);
        int spaceleft;
@@ -86,13 +94,13 @@ int fdt_create(void *buf, int bufsize)
 
        memset(buf, 0, bufsize);
 
-       fdt_set_magic(fdt, SW_MAGIC);
+       fdt_set_magic(fdt, FDT_SW_MAGIC);
        fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
        fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
        fdt_set_totalsize(fdt,  bufsize);
 
-       fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header),
-                                         sizeof(struct fdt_reserve_entry)));
+       fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
+                                             sizeof(struct fdt_reserve_entry)));
        fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
        fdt_set_off_dt_strings(fdt, bufsize);
 
@@ -102,11 +110,10 @@ int fdt_create(void *buf, int bufsize)
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
 {
        struct fdt_reserve_entry *re;
-       int err = check_header_sw(fdt);
        int offset;
 
-       if (err)
-               return err;
+       FDT_SW_CHECK_HEADER(fdt);
+
        if (fdt_size_dt_struct(fdt))
                return -FDT_ERR_BADSTATE;
 
@@ -114,7 +121,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
        if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
                return -FDT_ERR_NOSPACE;
 
-       re = (struct fdt_reserve_entry *)(fdt + offset);
+       re = (struct fdt_reserve_entry *)((char *)fdt + offset);
        re->address = cpu_to_fdt64(addr);
        re->size = cpu_to_fdt64(size);
 
@@ -131,13 +138,11 @@ int fdt_finish_reservemap(void *fdt)
 int fdt_begin_node(void *fdt, const char *name)
 {
        struct fdt_node_header *nh;
-       int err = check_header_sw(fdt);
        int namelen = strlen(name) + 1;
 
-       if (err)
-               return err;
+       FDT_SW_CHECK_HEADER(fdt);
 
-       nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
+       nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
        if (! nh)
                return -FDT_ERR_NOSPACE;
 
@@ -149,12 +154,10 @@ int fdt_begin_node(void *fdt, const char *name)
 int fdt_end_node(void *fdt)
 {
        uint32_t *en;
-       int err = check_header_sw(fdt);
 
-       if (err)
-               return err;
+       FDT_SW_CHECK_HEADER(fdt);
 
-       en = grab_space(fdt, FDT_TAGSIZE);
+       en = _fdt_grab_space(fdt, FDT_TAGSIZE);
        if (! en)
                return -FDT_ERR_NOSPACE;
 
@@ -162,7 +165,7 @@ int fdt_end_node(void *fdt)
        return 0;
 }
 
-static int find_add_string(void *fdt, const char *s)
+static int _fdt_find_add_string(void *fdt, const char *s)
 {
        char *strtab = (char *)fdt + fdt_totalsize(fdt);
        const char *p;
@@ -188,17 +191,15 @@ static int find_add_string(void *fdt, const char *s)
 int fdt_property(void *fdt, const char *name, const void *val, int len)
 {
        struct fdt_property *prop;
-       int err = check_header_sw(fdt);
        int nameoff;
 
-       if (err)
-               return err;
+       FDT_SW_CHECK_HEADER(fdt);
 
-       nameoff = find_add_string(fdt, name);
+       nameoff = _fdt_find_add_string(fdt, name);
        if (nameoff == 0)
                return -FDT_ERR_NOSPACE;
 
-       prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE));
+       prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
        if (! prop)
                return -FDT_ERR_NOSPACE;
 
@@ -211,18 +212,16 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
 
 int fdt_finish(void *fdt)
 {
-       int err = check_header_sw(fdt);
        char *p = (char *)fdt;
        uint32_t *end;
        int oldstroffset, newstroffset;
        uint32_t tag;
        int offset, nextoffset;
 
-       if (err)
-               return err;
+       FDT_SW_CHECK_HEADER(fdt);
 
        /* Add terminator */
-       end = grab_space(fdt, sizeof(*end));
+       end = _fdt_grab_space(fdt, sizeof(*end));
        if (! end)
                return -FDT_ERR_NOSPACE;
        *end = cpu_to_fdt32(FDT_END);
index 88e24b8318f449e4ab7902fc27b4e7345948299d..a4652c6e787ec8ef6823454eaa4c8932343863e2 100644 (file)
@@ -72,11 +72,11 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
        return 0;
 }
 
-static void nop_region(void *start, int len)
+static void _fdt_nop_region(void *start, int len)
 {
        uint32_t *p;
 
-       for (p = start; (void *)p < (start + len); p++)
+       for (p = start; (char *)p < ((char *)start + len); p++)
                *p = cpu_to_fdt32(FDT_NOP);
 }
 
@@ -89,7 +89,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
        if (! prop)
                return len;
 
-       nop_region(prop, len + sizeof(*prop));
+       _fdt_nop_region(prop, len + sizeof(*prop));
 
        return 0;
 }
@@ -139,6 +139,7 @@ int fdt_nop_node(void *fdt, int nodeoffset)
        if (endoffset < 0)
                return endoffset;
 
-       nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset);
+       _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
+                       endoffset - nodeoffset);
        return 0;
 }
index 6b2fb92ea3578b7a4b6fb5c49ee2c1d8f4ecee5a..ce80e4fb41b2b35533a54ac1b0b7fa47a1b53c9b 100644 (file)
 const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
 static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
 {
-       return (void *)fdt_offset_ptr(fdt, offset, checklen);
+       return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
 }
 
 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
 
+/**********************************************************************/
+/* Traversal functions                                                */
+/**********************************************************************/
+
+int fdt_next_node(const void *fdt, int offset, int *depth);
+
 /**********************************************************************/
 /* General functions                                                  */
 /**********************************************************************/
@@ -207,7 +213,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
 /**********************************************************************/
 
 /**
- * fdt_string - retreive a string from the strings block of a device tree
+ * fdt_string - retrieve a string from the strings block of a device tree
  * @fdt: pointer to the device tree blob
  * @stroffset: offset of the string within the strings block (native endian)
  *
@@ -221,7 +227,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
 const char *fdt_string(const void *fdt, int stroffset);
 
 /**
- * fdt_num_mem_rsv - retreive the number of memory reserve map entries
+ * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
  * @fdt: pointer to the device tree blob
  *
  * Returns the number of entries in the device tree blob's memory
@@ -234,7 +240,7 @@ const char *fdt_string(const void *fdt, int stroffset);
 int fdt_num_mem_rsv(const void *fdt);
 
 /**
- * fdt_get_mem_rsv - retreive one memory reserve map entry
+ * fdt_get_mem_rsv - retrieve one memory reserve map entry
  * @fdt: pointer to the device tree blob
  * @address, @size: pointers to 64-bit variables
  *
@@ -314,7 +320,7 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
 int fdt_path_offset(const void *fdt, const char *path);
 
 /**
- * fdt_get_name - retreive the name of a given node
+ * fdt_get_name - retrieve the name of a given node
  * @fdt: pointer to the device tree blob
  * @nodeoffset: structure block offset of the starting node
  * @lenp: pointer to an integer variable (will be overwritten) or NULL
@@ -346,7 +352,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
  * fdt_get_property() retrieves a pointer to the fdt_property
  * structure within the device tree blob corresponding to the property
  * named 'name' of the node at offset nodeoffset.  If lenp is
- * non-NULL, the length of the property value also returned, in the
+ * non-NULL, the length of the property value is also returned, in the
  * integer pointed to by lenp.
  *
  * returns:
@@ -369,8 +375,8 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
                                                      const char *name,
                                                      int *lenp)
 {
-       return (struct fdt_property *)fdt_get_property(fdt, nodeoffset,
-                                                      name, lenp);
+       return (struct fdt_property *)(uintptr_t)
+               fdt_get_property(fdt, nodeoffset, name, lenp);
 }
 
 /**
@@ -383,7 +389,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
  * fdt_getprop() retrieves a pointer to the value of the property
  * named 'name' of the node at offset nodeoffset (this will be a
  * pointer to within the device blob itself, not a copy of the value).
- * If lenp is non-NULL, the length of the property value also
+ * If lenp is non-NULL, the length of the property value is also
  * returned, in the integer pointed to by lenp.
  *
  * returns:
@@ -405,11 +411,11 @@ const void *fdt_getprop(const void *fdt, int nodeoffset,
 static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
                                  const char *name, int *lenp)
 {
-       return (void *)fdt_getprop(fdt, nodeoffset, name, lenp);
+       return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
 }
 
 /**
- * fdt_get_phandle - retreive the phandle of a given node
+ * fdt_get_phandle - retrieve the phandle of a given node
  * @fdt: pointer to the device tree blob
  * @nodeoffset: structure block offset of the node
  *
@@ -417,7 +423,7 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
  * structure block offset nodeoffset.
  *
  * returns:
- *     the phandle of the node at nodeoffset, on succes (!= 0, != -1)
+ *     the phandle of the node at nodeoffset, on success (!= 0, != -1)
  *     0, if the node has no phandle, or another error occurs
  */
 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
@@ -516,7 +522,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset);
  * structure from the start to nodeoffset, *twice*.
  *
  * returns:
- *     stucture block offset of the parent of the node at nodeoffset
+ *     structure block offset of the parent of the node at nodeoffset
  *             (>=0), on success
  *     -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
  *     -FDT_ERR_BADMAGIC,
@@ -573,7 +579,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
  * @fdt: pointer to the device tree blob
  * @phandle: phandle value
  *
- * fdt_node_offset_by_prop_value() returns the offset of the node
+ * fdt_node_offset_by_phandle() returns the offset of the node
  * which has the given phandle value.  If there is more than one node
  * in the tree with the given phandle (an invalid tree), results are
  * undefined.
@@ -655,8 +661,65 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
 /* Write-in-place functions                                           */
 /**********************************************************************/
 
+/**
+ * fdt_setprop_inplace - change a property's value, but not its size
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: pointer to data to replace the property value with
+ * @len: length of the property value
+ *
+ * fdt_setprop_inplace() replaces the value of a given property with
+ * the data in val, of length len.  This function cannot change the
+ * size of a property, and so will only work if len is equal to the
+ * current length of the property.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, if len is not equal to the property's current length
+ *     -FDT_ERR_NOTFOUND, node does not have the named property
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
                        const void *val, int len);
+
+/**
+ * fdt_setprop_inplace_cell - change the value of a single-cell property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: cell (32-bit integer) value to replace the property with
+ *
+ * fdt_setprop_inplace_cell() replaces the value of a given property
+ * with the 32-bit integer cell value in val, converting val to
+ * big-endian if necessary.  This function cannot change the size of a
+ * property, and so will only work if the property already exists and
+ * has length 4.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, if the property's length is not equal to 4
+  *    -FDT_ERR_NOTFOUND, node does not have the named property
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
                                           const char *name, uint32_t val)
 {
@@ -664,7 +727,54 @@ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
        return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
 }
 
+/**
+ * fdt_nop_property - replace a property with nop tags
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to nop
+ * @name: name of the property to nop
+ *
+ * fdt_nop_property() will replace a given property's representation
+ * in the blob with FDT_NOP tags, effectively removing it from the
+ * tree.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the property, and will not alter or move any other part of the
+ * tree.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOTFOUND, node does not have the named property
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_nop_node - replace a node (subtree) with nop tags
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to nop
+ *
+ * fdt_nop_node() will replace a given node's representation in the
+ * blob, including all its subnodes, if any, with FDT_NOP tags,
+ * effectively removing it from the tree.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the node and its properties and subnodes, and will not alter or
+ * move any other part of the tree.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_nop_node(void *fdt, int nodeoffset);
 
 /**********************************************************************/
@@ -693,23 +803,268 @@ int fdt_finish(void *fdt);
 int fdt_open_into(const void *fdt, void *buf, int bufsize);
 int fdt_pack(void *fdt);
 
+/**
+ * fdt_add_mem_rsv - add one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: 64-bit values (native endian)
+ *
+ * Adds a reserve map entry to the given blob reserving a region at
+ * address address of length size.
+ *
+ * This function will insert data into the reserve map and will
+ * therefore change the indexes of some entries in the table.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *             contain the new reservation entry
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
+
+/**
+ * fdt_del_mem_rsv - remove a memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @n: entry to remove
+ *
+ * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
+ * the blob.
+ *
+ * This function will delete data from the reservation table and will
+ * therefore change the indexes of some entries in the table.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
+ *             are less than n+1 reserve map entries)
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_del_mem_rsv(void *fdt, int n);
 
+/**
+ * fdt_set_name - change the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ * @name: name to give the node
+ *
+ * fdt_set_name() replaces the name (including unit address, if any)
+ * of the given node with the given string.  NOTE: this function can't
+ * efficiently check if the new name is unique amongst the given
+ * node's siblings; results are undefined if this function is invoked
+ * with a name equal to one of the given node's siblings.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, there is insufficient free space in the blob
+ *             to contain the new name
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_set_name(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_setprop - create or change a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: pointer to data to set the property value to
+ * @len: length of the property value
+ *
+ * fdt_setprop() sets the value of the named property in the given
+ * node to the given value and length, creating the property if it
+ * does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *             contain the new property value
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
                const void *val, int len);
+
+/**
+ * fdt_setprop_cell - set a property to a single cell value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_cell() sets the value of the named property in the
+ * given node to the given cell value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *             contain the new property value
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
                                   uint32_t val)
 {
        val = cpu_to_fdt32(val);
        return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
 }
+
+/**
+ * fdt_setprop_string - set a property to a string value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value for the property
+ *
+ * fdt_setprop_string() sets the value of the named property in the
+ * given node to the given string value (using the length of the
+ * string to determine the new length of the property), or creates a
+ * new property with that value if it does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *             contain the new property value
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
        fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+/**
+ * fdt_delprop - delete a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to nop
+ * @name: name of the property to nop
+ *
+ * fdt_del_property() will delete the given property.
+ *
+ * This function will delete data from the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_NOTFOUND, node does not have the named property
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_add_subnode_namelen - creates a new node based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_add_subnode(), but use only the first namelen
+ * characters of name as the name of the new node.  This is useful for
+ * creating subnodes based on a portion of a larger string, such as a
+ * full path.
+ */
 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
                            const char *name, int namelen);
+
+/**
+ * fdt_add_subnode - creates a new node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_add_subnode() creates a new node as a subnode of the node at
+ * structure block offset parentoffset, with the given name (which
+ * should include the unit address, if any).
+ *
+ * This function will insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+
+ * returns:
+ *     structure block offset of the created nodeequested subnode (>=0), on success
+ *     -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ *     -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
+ *     -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
+ *             the given name
+ *     -FDT_ERR_NOSPACE, if there is insufficient free space in the
+ *             blob to contain the new node
+ *     -FDT_ERR_NOSPACE
+ *     -FDT_ERR_BADLAYOUT
+ *      -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings.
+ */
 int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+
+/**
+ * fdt_del_node - delete a node (subtree)
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to nop
+ *
+ * fdt_del_node() will remove the given node, including all its
+ * subnodes if any, from the blob.
+ *
+ * This function will delete data from the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ *     0, on success
+ *     -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *     -FDT_ERR_BADLAYOUT,
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
 int fdt_del_node(void *fdt, int nodeoffset);
 
 /**********************************************************************/
index 1e60936beb5bbff7d609fc55011430fdadc8bd82..46eb93e4af5c471ecac7bc470065c11f6ae6f9e6 100644 (file)
  */
 #include <fdt.h>
 
-#define ALIGN(x, a)    (((x) + (a) - 1) & ~((a) - 1))
-#define PALIGN(p, a)   ((void *)ALIGN((unsigned long)(p), (a)))
+#define FDT_ALIGN(x, a)                (((x) + (a) - 1) & ~((a) - 1))
+#define FDT_TAGALIGN(x)                (FDT_ALIGN((x), FDT_TAGSIZE))
 
-#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
-#define streq(p, q)    (strcmp((p), (q)) == 0)
+#define FDT_CHECK_HEADER(fdt) \
+       { \
+               int err; \
+               if ((err = fdt_check_header(fdt)) != 0) \
+                       return err; \
+       }
 
 uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
+int _fdt_check_node_offset(const void *fdt, int offset);
 const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
 int _fdt_node_end_offset(void *fdt, int nodeoffset);
 
 static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
 {
-       return fdt + fdt_off_dt_struct(fdt) + offset;
+       return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
 }
 
 static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
 {
-       return (void *)_fdt_offset_ptr(fdt, offset);
+       return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
 }
 
 static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
 {
        const struct fdt_reserve_entry *rsv_table =
-               fdt + fdt_off_mem_rsvmap(fdt);
+               (const struct fdt_reserve_entry *)
+               ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
 
        return rsv_table + n;
 }
 static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
 {
-       return (void *)_fdt_mem_rsv(fdt, n);
+       return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
 }
 
-#define SW_MAGIC               (~FDT_MAGIC)
+#define FDT_SW_MAGIC           (~FDT_MAGIC)
 
 #endif /* _LIBFDT_INTERNAL_H */
index a4b0fc959ecebc34d96997cb898ae956b1c7272a..c89fdb1b80e161e78888cf6fc61de13035cd263c 100644 (file)
@@ -6,6 +6,7 @@
 
 typedef u32 uint32_t;
 typedef u64 uint64_t;
+typedef unsigned long uintptr_t;
 
 #define fdt16_to_cpu(x)                (x)
 #define cpu_to_fdt16(x)                (x)
index 965c237c122d781063697dff3a9cef20dd2859ca..ee0dc41d7c5659bb063e37b23bf180b2c8ba578b 100755 (executable)
@@ -307,7 +307,9 @@ fi
 # post-processing needed for some platforms
 case "$platform" in
 pseries|chrp)
-    $objbin/addnote "$ofile"
+    ${CROSS}objcopy -O binary -j .fakeelf "$kernel" "$ofile".rpanote
+    $objbin/addnote "$ofile" "$ofile".rpanote
+    rm -r "$ofile".rpanote
     ;;
 coff)
     ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
diff --git a/arch/powerpc/configs/44x/arches_defconfig b/arch/powerpc/configs/44x/arches_defconfig
new file mode 100644 (file)
index 0000000..70f4607
--- /dev/null
@@ -0,0 +1,767 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc5
+# Wed Oct  1 15:54:57 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+CONFIG_PPC4xx_PCI_EXPRESS=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+CONFIG_ARCHES=y
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+# CONFIG_YOSEMITE is not set
+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
+CONFIG_PPC44x_SIMPLE=y
+CONFIG_460EX=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=256
+CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index 5e6780a088ce591d1690b5594dab9181a71682c2..0b1fa20f745ce6cd988c8fa60b2d6a8a44fb05a8 100644 (file)
@@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index 2028337868b4f28a78b881cc17599087d1dccfce..b7eae2bdf19c1b731a40fda61411d2cde532f048 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index dd80eb0a87a100ee42ff3f1cdbb0b6ce3e1d30b0..b0a27a67d8c7c145d31f765c5e4119dc719ac814 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index bdf50c8a17e6b86ca109ba0fbdd466e24bb4f94f..ad825bcddd1fab5b35d6c0e972301645b8d23acc 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index 4eef8c95480ed6c4da4310cc7ed1fa89e692ccda..38267501f44ddfb9329b1a5b6946f9daf0470d57 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index 8d6513931850d4b888d3d23615ae8dd92da9e315..90aab340e7ff30f679fac524bffe7f6da23e841d 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index a8afa39d6f76cf834cfb1715750e5c2dccf1a775..7458a242d251b37fc9e72e20e35cbce409770ae1 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index 24c320a36670642e359d960dbd82ec3e2d6e06de..1a92798938cf9d458ea6c953d6fa9e621c07d7be 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index e029e9e1462208ad30007a2040b19b5740907557..03d8cede02727b447f3ddd101cfab8da57c49444 100644 (file)
@@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
@@ -383,7 +383,84 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_OF_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
index 7d674be702fe75c1280c6dccdf6ffa68e0ac6ab8..cdf84177370a4a1be216db4785461cecbebf2207 100644 (file)
@@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index de472022aa81d4057cecc0ac19aeb3a38d9756f2..97e02d7a5b0960d62d42648d63013e1e6364a659 100644 (file)
@@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index e8d2d691d26c9d7efeb73c26e50f2c5ff1e3511a..5ac33054ce2c81a24dceb892b7f303296682dc06 100644 (file)
@@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index 9245a67da20029e2cb179ff12f7743bc80fa2ee2..c359cc2a380e2f7cd84ee9a96048b0100c9ebb7c 100644 (file)
@@ -162,11 +162,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
new file mode 100644 (file)
index 0000000..312d7af
--- /dev/null
@@ -0,0 +1,1657 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26-rc5
+# Wed Jun 11 12:06:53 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_86xx=y
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_MPC8641_HPCN is not set
+# CONFIG_SBC8641D is not set
+# CONFIG_MPC8610_HPCD is not set
+CONFIG_GEF_SBC610=y
+CONFIG_MPC8641=y
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+CONFIG_PCI_DEBUG=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_HAS_RAPIDIO=y
+# CONFIG_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+# CONFIG_IP_NF_MATCH_AH is not set
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+# CONFIG_IP_DCCP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+# CONFIG_NET_SCH_RR is not set
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_OF_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+# CONFIG_MTD_CFI_NOSWAP is not set
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_FSL is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_GFAR_NAPI is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_ATM_DRIVERS=y
+# CONFIG_ATM_DUMMY is not set
+# CONFIG_ATM_TCP is not set
+# CONFIG_ATM_LANAI is not set
+# CONFIG_ATM_ENI is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+# CONFIG_ATM_NICSTAR is not set
+# CONFIG_ATM_IDT77252 is not set
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+# CONFIG_ATM_FORE200E_MAYBE is not set
+# CONFIG_ATM_HE is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+# CONFIG_PPPOL2TP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_DS1682=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_LM92=y
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_FSL is not set
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_ATM is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUGGER=y
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
similarity index 99%
rename from arch/powerpc/configs/mpc8610_hpcd_defconfig
rename to arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
index 1a9990731eb08a57182a48729d5134d8e85f1e15..c98c6ee44492b4a591a372353a7d8d6de6204226 100644 (file)
@@ -165,11 +165,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
similarity index 99%
rename from arch/powerpc/configs/mpc8641_hpcn_defconfig
rename to arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
index ea09be31b6ea0b7bd5e4ed8832b93238966afe8d..444ddf98436d2f4b6fbef558fa949e8b7a0d313f 100644 (file)
@@ -167,11 +167,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
similarity index 99%
rename from arch/powerpc/configs/sbc8641d_defconfig
rename to arch/powerpc/configs/86xx/sbc8641d_defconfig
index f545421f9857ff74f5e4c576c40e58739f010ad7..d900f8f376cf70535ca8dc7d3799c58b5e134605 100644 (file)
@@ -166,11 +166,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
index ef0c6e8005089580dc11ec3d50449ddd45dcf314..cd691f7708108662f1ac8b4b945043789fd2750c 100644 (file)
@@ -150,11 +150,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 CONFIG_PPC_82xx=y
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
new file mode 100644 (file)
index 0000000..cc9eaba
--- /dev/null
@@ -0,0 +1,900 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26-rc2
+# Thu May 22 08:18:47 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_PPC_82xx=y
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_MPC8272_ADS is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_EP8248E is not set
+CONFIG_MGCOGE=y
+# CONFIG_PQ2ADS is not set
+CONFIG_8260=y
+CONFIG_8272=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPM2=y
+CONFIG_PPC_CPM_NEW_BINDING=y
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_CPM=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_FSL_SOC=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+CONFIG_FIXED_PHY=y
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_FS_ENET=y
+CONFIG_FS_ENET_HAS_SCC=y
+# CONFIG_FS_ENET_HAS_FCC is not set
+# CONFIG_FS_ENET_MDIO_FCC is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_CPM_SCC1 is not set
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+CONFIG_SERIAL_CPM_SMC1=y
+CONFIG_SERIAL_CPM_SMC2=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+CONFIG_BDI_SWITCH=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_PCBC=y
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+CONFIG_PPC_LIB_RHEAP=y
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/mgsuvd_defconfig b/arch/powerpc/configs/mgsuvd_defconfig
new file mode 100644 (file)
index 0000000..3cd6ce4
--- /dev/null
@@ -0,0 +1,872 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26-rc2
+# Wed May 21 13:30:33 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+CONFIG_PPC_8xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_8xx=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+# CONFIG_BUG is not set
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+# CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+CONFIG_CPM1=y
+# CONFIG_MPC8XXFADS is not set
+# CONFIG_MPC86XADS is not set
+# CONFIG_MPC885ADS is not set
+# CONFIG_PPC_EP88XC is not set
+# CONFIG_PPC_ADDER875 is not set
+CONFIG_PPC_MGSUVD=y
+
+#
+# MPC8xx CPM Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+CONFIG_8xx_CPU15=y
+# CONFIG_NO_UCODE_PATCH is not set
+# CONFIG_USB_SOF_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_UCODE_PATCH is not set
+CONFIG_I2C_SPI_SMC1_UCODE_PATCH=y
+CONFIG_UCODE_PATCH=y
+# CONFIG_PQ2ADS is not set
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_CPM_NEW_BINDING=y
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_CPM=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_FSL_SOC=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCI_QSPAN is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xfd000000
+CONFIG_CONSISTENT_SIZE=0x00200000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_CFI_FLAGADM is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+CONFIG_FIXED_PHY=y
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_FS_ENET=y
+CONFIG_FS_ENET_HAS_SCC=y
+# CONFIG_FS_ENET_HAS_FEC is not set
+# CONFIG_FS_ENET_MDIO_FEC is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_CPM_SCC1 is not set
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+CONFIG_SERIAL_CPM_SMC1=y
+# CONFIG_SERIAL_CPM_SMC2 is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
+CONFIG_PPC_LIB_RHEAP=y
+# CONFIG_VIRTUALIZATION is not set
index 7c435c84c8751dc91d271e96109686f47a12f99a..ff6f7c475f47ceacbf4b30fdb536dc21866f8985 100644 (file)
@@ -151,11 +151,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 CONFIG_PPC_82xx=y
index 916e3df7cc451496e0403c49f5964dbe6e8c276f..991c9bda12a98cba9c758105584310007bf6780d 100644 (file)
@@ -166,11 +166,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_82xx is not set
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig
new file mode 100644 (file)
index 0000000..9d4be82
--- /dev/null
@@ -0,0 +1,1646 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc5
+# Tue Sep 23 23:28:38 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_MPC8xxx_GPIO is not set
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_86xx=y
+CONFIG_MPC8641_HPCN=y
+CONFIG_SBC8641D=y
+CONFIG_MPC8610_HPCD=y
+CONFIG_GEF_SBC610=y
+CONFIG_MPC8641=y
+CONFIG_MPC8610=y
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+CONFIG_FSL_ULI1575=y
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_HAS_RAPIDIO=y
+# CONFIG_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=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=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_SATA_AHCI=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_FSL is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+CONFIG_PATA_ALI=y
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_SFC is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+CONFIG_SENSORS_EEPROM=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+# CONFIG_TTPCI_EEPROM is not set
+# CONFIG_DVB_BUDGET_CORE is not set
+
+#
+# Supported USB Adapters
+#
+# CONFIG_DVB_USB is not set
+# CONFIG_DVB_TTUSB_BUDGET is not set
+# CONFIG_DVB_TTUSB_DEC is not set
+# CONFIG_DVB_CINERGYT2 is not set
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported BT878 Adapters
+#
+
+#
+# Supported Pluto2 Adapters
+#
+# CONFIG_DVB_PLUTO2 is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+# CONFIG_DVB_CX24110 is not set
+# CONFIG_DVB_CX24123 is not set
+# CONFIG_DVB_MT312 is not set
+# CONFIG_DVB_S5H1420 is not set
+# CONFIG_DVB_STV0299 is not set
+# CONFIG_DVB_TDA8083 is not set
+# CONFIG_DVB_TDA10086 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_TUNER_ITD1000 is not set
+# CONFIG_DVB_TDA826X is not set
+# CONFIG_DVB_TUA6100 is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+# CONFIG_DVB_SP8870 is not set
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_CX22700 is not set
+# CONFIG_DVB_CX22702 is not set
+# CONFIG_DVB_DRX397XD is not set
+# CONFIG_DVB_L64781 is not set
+# CONFIG_DVB_TDA1004X is not set
+# CONFIG_DVB_NXT6000 is not set
+# CONFIG_DVB_MT352 is not set
+# CONFIG_DVB_ZL10353 is not set
+# CONFIG_DVB_DIB3000MB is not set
+# CONFIG_DVB_DIB3000MC is not set
+# CONFIG_DVB_DIB7000M is not set
+# CONFIG_DVB_DIB7000P is not set
+# CONFIG_DVB_TDA10048 is not set
+
+#
+# DVB-C (cable) frontends
+#
+# CONFIG_DVB_VES1820 is not set
+# CONFIG_DVB_TDA10021 is not set
+# CONFIG_DVB_TDA10023 is not set
+# CONFIG_DVB_STV0297 is not set
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LGDT330X is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_AU8522 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+# CONFIG_DVB_PLL is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+
+#
+# SEC control devices for DVB-S
+#
+# CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_ISL6405 is not set
+# CONFIG_DVB_ISL6421 is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5530 is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_HIFIER is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+CONFIG_SND_INTEL8X0=y
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_PPC=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_FSL is not set
+CONFIG_USB_EHCI_HCD_PPC_OF=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_SIERRA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=y
+CONFIG_VXFS_FS=m
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+# CONFIG_ROMFS_FS is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_TALITOS is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index b390b74766499bf3ad8a7458b71f3444ee960a13..7e17862c38b8f933edbfb1d60b34b84a60714b72 100644 (file)
@@ -152,11 +152,11 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_CLASSIC32=y
-CONFIG_PPC_CHRP=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
 # CONFIG_PPC_MPC52xx is not set
-CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 CONFIG_PPC_82xx=y
index ef8a248dfd558697a374868bf35f4b8e8d5950d1..1e94b07a020ed6907be0fd1d35a2ec58b4d5b852 100644 (file)
@@ -62,6 +62,7 @@ enum powerpc_pmc_type {
        PPC_PMC_DEFAULT = 0,
        PPC_PMC_IBM = 1,
        PPC_PMC_PA6T = 2,
+       PPC_PMC_G4 = 3,
 };
 
 struct pt_regs;
@@ -192,6 +193,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_NO_SLBIE_B             LONG_ASM_CONST(0x0008000000000000)
 #define CPU_FTR_VSX                    LONG_ASM_CONST(0x0010000000000000)
 #define CPU_FTR_SAO                    LONG_ASM_CONST(0x0020000000000000)
+#define CPU_FTR_CP_USE_DCBTZ           LONG_ASM_CONST(0x0040000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -387,10 +389,11 @@ extern const char *powerpc_base_platform;
            CPU_FTR_MMCRA | CPU_FTR_CTRL)
 #define CPU_FTRS_POWER4        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
-           CPU_FTR_MMCRA)
+           CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ)
 #define CPU_FTRS_PPC970        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
-           CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
+           CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
+           CPU_FTR_CP_USE_DCBTZ)
 #define CPU_FTRS_POWER5        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -411,7 +414,8 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
-           CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
+           CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \
+           CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ)
 #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
index f15296cf35988c7e78a1d1d0236ae843bde73005..828e3aa1f2fcb007aa8ec4ace12004fffd36b74e 100644 (file)
 #define SDR0_UART3             0x0123
 #define SDR0_CUST0             0x4000
 
+/* SDR for 405EZ */
+#define DCRN_SDR_ICINTSTAT     0x4510
+#define ICINTSTAT_ICRX 0x80000000
+#define ICINTSTAT_ICTX0        0x40000000
+#define ICINTSTAT_ICTX1 0x20000000
+#define ICINTSTAT_ICTX 0x60000000
+
 /* SDRs (460EX/460GT) */
 #define SDR0_ETH_CFG           0x4103
 #define SDR0_ETH_CFG_ECS       0x00000100      /* EMAC int clk source */
index 228ab2a315b9cd1354004bb96a77419574c52af8..dfd504caccc1c711216adc077b351eb5710f32ca 100644 (file)
@@ -16,9 +16,6 @@ struct dev_archdata {
        /* DMA operations on that device */
        struct dma_mapping_ops  *dma_ops;
        void                    *dma_data;
-
-       /* NUMA node if applicable */
-       int                     numa_node;
 };
 
 #endif /* _ASM_POWERPC_DEVICE_H */
index c7ca45f97dd210e9ef611ba8d4877b6f64067021..fddb229bd74f270231c570726d7e15bef0a201f5 100644 (file)
@@ -44,8 +44,6 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
 
 #endif /* ! CONFIG_NOT_COHERENT_CACHE */
 
-#ifdef CONFIG_PPC64
-
 static inline unsigned long device_to_mask(struct device *dev)
 {
        if (dev->dma_mask && *dev->dma_mask)
@@ -76,8 +74,24 @@ struct dma_mapping_ops {
                                struct dma_attrs *attrs);
        int             (*dma_supported)(struct device *dev, u64 mask);
        int             (*set_dma_mask)(struct device *dev, u64 dma_mask);
+       dma_addr_t      (*map_page)(struct device *dev, struct page *page,
+                               unsigned long offset, size_t size,
+                               enum dma_data_direction direction,
+                               struct dma_attrs *attrs);
+       void            (*unmap_page)(struct device *dev,
+                               dma_addr_t dma_address, size_t size,
+                               enum dma_data_direction direction,
+                               struct dma_attrs *attrs);
 };
 
+/*
+ * Available generic sets of operations
+ */
+#ifdef CONFIG_PPC64
+extern struct dma_mapping_ops dma_iommu_ops;
+#endif
+extern struct dma_mapping_ops dma_direct_ops;
+
 static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
 {
        /* We don't handle the NULL dev case for ISA for now. We could
@@ -85,8 +99,19 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
         * only ISA DMA device we support is the floppy and we have a hack
         * in the floppy driver directly to get a device for us.
         */
-       if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL))
+
+       if (unlikely(dev == NULL) || dev->archdata.dma_ops == NULL) {
+#ifdef CONFIG_PPC64
                return NULL;
+#else
+               /* Use default on 32-bit if dma_ops is not set up */
+               /* TODO: Long term, we should fix drivers so that dev and
+                * archdata dma_ops are set up for all buses.
+                */
+               return &dma_direct_ops;
+#endif
+       }
+
        return dev->archdata.dma_ops;
 }
 
@@ -123,6 +148,12 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
        return 0;
 }
 
+/*
+ * TODO: map_/unmap_single will ideally go away, to be completely
+ * replaced by map/unmap_page.   Until then, we allow dma_ops to have
+ * one or the other, or both by checking to see if the specific
+ * function requested exists; and if not, falling back on the other set.
+ */
 static inline dma_addr_t dma_map_single_attrs(struct device *dev,
                                              void *cpu_addr,
                                              size_t size,
@@ -132,7 +163,14 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev,
        struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
        BUG_ON(!dma_ops);
-       return dma_ops->map_single(dev, cpu_addr, size, direction, attrs);
+
+       if (dma_ops->map_single)
+               return dma_ops->map_single(dev, cpu_addr, size, direction,
+                                          attrs);
+
+       return dma_ops->map_page(dev, virt_to_page(cpu_addr),
+                                (unsigned long)cpu_addr % PAGE_SIZE, size,
+                                direction, attrs);
 }
 
 static inline void dma_unmap_single_attrs(struct device *dev,
@@ -144,7 +182,13 @@ static inline void dma_unmap_single_attrs(struct device *dev,
        struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
        BUG_ON(!dma_ops);
-       dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
+
+       if (dma_ops->unmap_single) {
+               dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
+               return;
+       }
+
+       dma_ops->unmap_page(dev, dma_addr, size, direction, attrs);
 }
 
 static inline dma_addr_t dma_map_page_attrs(struct device *dev,
@@ -156,8 +200,13 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev,
        struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
        BUG_ON(!dma_ops);
+
+       if (dma_ops->map_page)
+               return dma_ops->map_page(dev, page, offset, size, direction,
+                                        attrs);
+
        return dma_ops->map_single(dev, page_address(page) + offset, size,
-                       direction, attrs);
+                                  direction, attrs);
 }
 
 static inline void dma_unmap_page_attrs(struct device *dev,
@@ -169,6 +218,12 @@ static inline void dma_unmap_page_attrs(struct device *dev,
        struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
        BUG_ON(!dma_ops);
+
+       if (dma_ops->unmap_page) {
+               dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
+               return;
+       }
+
        dma_ops->unmap_single(dev, dma_address, size, direction, attrs);
 }
 
@@ -253,126 +308,6 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
        dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
 }
 
-/*
- * Available generic sets of operations
- */
-extern struct dma_mapping_ops dma_iommu_ops;
-extern struct dma_mapping_ops dma_direct_ops;
-
-#else /* CONFIG_PPC64 */
-
-#define dma_supported(dev, mask)       (1)
-
-static inline int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = dma_mask;
-
-       return 0;
-}
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-                                      dma_addr_t * dma_handle,
-                                      gfp_t gfp)
-{
-#ifdef CONFIG_NOT_COHERENT_CACHE
-       return __dma_alloc_coherent(size, dma_handle, gfp);
-#else
-       void *ret;
-       /* ignore region specifiers */
-       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
-       if (dev == NULL || dev->coherent_dma_mask < 0xffffffff)
-               gfp |= GFP_DMA;
-
-       ret = (void *)__get_free_pages(gfp, get_order(size));
-
-       if (ret != NULL) {
-               memset(ret, 0, size);
-               *dma_handle = virt_to_bus(ret);
-       }
-
-       return ret;
-#endif
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-                 dma_addr_t dma_handle)
-{
-#ifdef CONFIG_NOT_COHERENT_CACHE
-       __dma_free_coherent(size, vaddr);
-#else
-       free_pages((unsigned long)vaddr, get_order(size));
-#endif
-}
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       __dma_sync(ptr, size, direction);
-
-       return virt_to_bus(ptr);
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-                                   size_t size,
-                                   enum dma_data_direction direction)
-{
-       /* We do nothing. */
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-            unsigned long offset, size_t size,
-            enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       __dma_sync_page(page, offset, size, direction);
-
-       return page_to_bus(page) + offset;
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-                                 size_t size,
-                                 enum dma_data_direction direction)
-{
-       /* We do nothing. */
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-          enum dma_data_direction direction)
-{
-       struct scatterlist *sg;
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       for_each_sg(sgl, sg, nents, i) {
-               BUG_ON(!sg_page(sg));
-               __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
-               sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
-       }
-
-       return nents;
-}
-
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-                               int nhwentries,
-                               enum dma_data_direction direction)
-{
-       /* We don't do anything here. */
-}
-
-#endif /* CONFIG_PPC64 */
-
 static inline void dma_sync_single_for_cpu(struct device *dev,
                dma_addr_t dma_handle, size_t size,
                enum dma_data_direction direction)
index 64c6ee22eefd6ba4cb6dd5da54bd801440111c2a..d812929390e45e602b0a2e02506c7e4e4ac1474c 100644 (file)
@@ -232,7 +232,7 @@ typedef elf_vrregset_t elf_fpxregset_t;
 #endif /* __powerpc64__ */
 
 #ifdef __powerpc64__
-# define SET_PERSONALITY(ex, ibcs2)                            \
+# define SET_PERSONALITY(ex)                                   \
 do {                                                           \
        unsigned long new_flags = 0;                            \
        if ((ex).e_ident[EI_CLASS] == ELFCLASS32)               \
@@ -256,7 +256,7 @@ do {                                                                \
 # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
                (exec_stk != EXSTACK_DISABLE_X) : 0)
 #else 
-# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+# define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 #endif /* __powerpc64__ */
 
 extern int dcache_bsize;
index 329148b5acc6478fb37afedb7affb3c89738eb37..d3d4534e3c74888e55e26e43e083a3a138ff8b81 100644 (file)
  * low halfword of the address, but for Kdump we need the whole low
  * word.
  */
-#ifdef CONFIG_CRASH_DUMP
 #define LOAD_HANDLER(reg, label)                                       \
-       oris    reg,reg,(label)@h;      /* virt addr of handler ... */  \
-       ori     reg,reg,(label)@l;      /* .. and the rest */
-#else
-#define LOAD_HANDLER(reg, label)                                       \
-       ori     reg,reg,(label)@l;      /* virt addr of handler ... */
-#endif
+       addi    reg,reg,(label)-_stext; /* virt addr of handler ... */
 
 #define EXCEPTION_PROLOG_1(area)                               \
        mfspr   r13,SPRN_SPRG3;         /* get paca address into r13 */ \
        std     r9,area+EX_R13(r13);                                    \
        mfcr    r9
 
-/*
- * Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode.
- * The firmware calls the registered system_reset_fwnmi and
- * machine_check_fwnmi handlers in 32bit mode if the cpu happens to run
- * a 32bit application at the time of the event.
- * This firmware bug is present on POWER4 and JS20.
- */
-#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label)              \
-       EXCEPTION_PROLOG_1(area);                                       \
-       clrrdi  r12,r13,32;             /* get high part of &label */   \
-       mfmsr   r10;                                                    \
-       /* force 64bit mode */                                          \
-       li      r11,5;                  /* MSR_SF_LG|MSR_ISF_LG */      \
-       rldimi  r10,r11,61,0;           /* insert into top 3 bits */    \
-       /* done 64bit mode */                                           \
-       mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
-       LOAD_HANDLER(r12,label)                                         \
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
-       mtspr   SPRN_SRR0,r12;                                          \
-       mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
-       mtspr   SPRN_SRR1,r10;                                          \
-       rfid;                                                           \
-       b       .       /* prevent speculative execution */
-
 #define EXCEPTION_PROLOG_PSERIES(area, label)                          \
        EXCEPTION_PROLOG_1(area);                                       \
-       clrrdi  r12,r13,32;             /* get high part of &label */   \
-       mfmsr   r10;                                                    \
+       ld      r12,PACAKBASE(r13);     /* get high part of &label */   \
+       ld      r10,PACAKMSR(r13);      /* get MSR value for kernel */  \
        mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
        LOAD_HANDLER(r12,label)                                         \
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
        mtspr   SPRN_SRR0,r12;                                          \
        mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
        mtspr   SPRN_SRR1,r10;                                          \
@@ -210,11 +179,10 @@ label##_pSeries:                                                  \
        std     r10,PACA_EXGEN+EX_R13(r13);                             \
        std     r11,PACA_EXGEN+EX_R11(r13);                             \
        std     r12,PACA_EXGEN+EX_R12(r13);                             \
-       clrrdi  r12,r13,32;             /* get high part of &label */   \
-       mfmsr   r10;                                                    \
+       ld      r12,PACAKBASE(r13);     /* get high part of &label */   \
+       ld      r10,PACAKMSR(r13);      /* get MSR value for kernel */  \
        mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
        LOAD_HANDLER(r12,label##_common)                                \
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
        mtspr   SPRN_SRR0,r12;                                          \
        mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
        mtspr   SPRN_SRR1,r10;                                          \
index 303f5484c0507154a8177614eb8b3d6a83a538cd..63a4f779f5312d54281373c29bd319ce74a4f6ca 100644 (file)
@@ -23,9 +23,9 @@
 #ifndef __ASM_FSL_LBC_H
 #define __ASM_FSL_LBC_H
 
+#include <linux/compiler.h>
 #include <linux/types.h>
-#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 struct fsl_lbc_bank {
        __be32 br;             /**< Base Register  */
@@ -227,9 +227,6 @@ struct fsl_lbc_regs {
        u8 res8[0xF00];
 };
 
-extern struct fsl_lbc_regs __iomem *fsl_lbc_regs;
-extern spinlock_t fsl_lbc_lock;
-
 /*
  * FSL UPM routines
  */
@@ -268,44 +265,7 @@ static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
                cpu_relax();
 }
 
-/**
- * fsl_upm_run_pattern - actually run an UPM pattern
- * @upm:       pointer to the fsl_upm structure obtained via fsl_upm_find
- * @io_base:   remapped pointer to where memory access should happen
- * @mar:       MAR register content during pattern execution
- *
- * This function triggers dummy write to the memory specified by the io_base,
- * thus UPM pattern actually executed. Note that mar usage depends on the
- * pre-programmed AMX bits in the UPM RAM.
- */
-static inline int fsl_upm_run_pattern(struct fsl_upm *upm,
-                                     void __iomem *io_base, u32 mar)
-{
-       int ret = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&fsl_lbc_lock, flags);
-
-       out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
-
-       switch (upm->width) {
-       case 8:
-               out_8(io_base, 0x0);
-               break;
-       case 16:
-               out_be16(io_base, 0x0);
-               break;
-       case 32:
-               out_be32(io_base, 0x0);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-
-       spin_unlock_irqrestore(&fsl_lbc_lock, flags);
-
-       return ret;
-}
+extern int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base,
+                              u32 mar);
 
 #endif /* __ASM_FSL_LBC_H */
index 5d99b6489d569d44e54a3781734e797d72100b5c..91c589520c0aa65256f954c0fce003e37a527b5d 100644 (file)
@@ -84,7 +84,7 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro
 #ifdef CONFIG_DEBUG_HIGHMEM
        BUG_ON(!pte_none(*(kmap_pte-idx)));
 #endif
-       set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
+       __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
        flush_tlb_page(NULL, vaddr);
 
        return (void*) vaddr;
index 77c7fa025e658cd736175f16fc4e2144538cdd19..08266d2728b315f78d4b48231d5ac2db7bce2eb4 100644 (file)
@@ -711,7 +711,7 @@ static inline void * phys_to_virt(unsigned long address)
 /*
  * Change "struct page" to physical address.
  */
-#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+#define page_to_phys(page)     ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT)
 
 /* We do NOT want virtual merging, it would put too much pressure on
  * our iommu allocator. Instead, we want drivers to be smart enough
index a372f76836c23145586144933e4f03f4b63bd692..0a5137676e1b89f4f76d2532d820399c2413743c 100644 (file)
@@ -236,15 +236,27 @@ extern unsigned int irq_find_mapping(struct irq_host *host,
 extern unsigned int irq_create_direct_mapping(struct irq_host *host);
 
 /**
- * irq_radix_revmap - Find a linux virq from a hw irq number.
+ * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
+ * @host: host owning this hardware interrupt
+ * @virq: linux irq number
+ * @hwirq: hardware irq number in that host space
+ *
+ * This is for use by irq controllers that use a radix tree reverse
+ * mapping for fast lookup.
+ */
+extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
+                                   irq_hw_number_t hwirq);
+
+/**
+ * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
  * @host: host owning this hardware interrupt
  * @hwirq: hardware irq number in that host space
  *
  * This is a fast path, for use by irq controller code that uses radix tree
  * revmaps
  */
-extern unsigned int irq_radix_revmap(struct irq_host *host,
-                                    irq_hw_number_t hwirq);
+extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
+                                           irq_hw_number_t hwirq);
 
 /**
  * irq_linear_revmap - Find a linux virq from a hw irq number.
index 893aafd87fde2b20ce7eda9dee61f30b79c9ec91..2740c44ff71766e5e9dad9c01b33e7377d0d4bbd 100644 (file)
@@ -88,8 +88,6 @@ struct machdep_calls {
        unsigned long   (*tce_get)(struct iommu_table *tbl,
                                    long index);
        void            (*tce_flush)(struct iommu_table *tbl);
-       void            (*pci_dma_dev_setup)(struct pci_dev *dev);
-       void            (*pci_dma_bus_setup)(struct pci_bus *bus);
 
        void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
                                   unsigned long flags);
@@ -101,6 +99,9 @@ struct machdep_calls {
 #endif
 #endif /* CONFIG_PPC64 */
 
+       void            (*pci_dma_dev_setup)(struct pci_dev *dev);
+       void            (*pci_dma_bus_setup)(struct pci_bus *bus);
+
        int             (*probe)(void);
        void            (*setup_arch)(void); /* Optional, may be NULL */
        void            (*init_early)(void);
index 9209f755763e100bd93a3b8046098a09c4972de1..e7b99bac9f4875312655e1f3b44799b6734f6a16 100644 (file)
@@ -44,7 +44,7 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot)
 
 static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
 {
-       return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : 0;
+       return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0);
 }
 #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags)
 
index c2df53c5ceb9a253c7c4661731b67397b14afac3..5a441742ffba45434038716ae368aa516eccbdfe 100644 (file)
@@ -437,7 +437,7 @@ typedef struct {
        })
 #endif /* 1 */
 
-/* This is only valid for addresses >= KERNELBASE */
+/* This is only valid for addresses >= PAGE_OFFSET */
 static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
 {
        if (ssize == MMU_SEGSIZE_256M)
index fe566a348a86e7e770ab014b11d96b380563183f..34d9ac433ace02fc169be44afc3fdd450bfb615c 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/irq.h>
 #include <linux/sysdev.h>
 #include <asm/dcr.h>
+#include <asm/msi_bitmap.h>
 
 /*
  * Global registers
@@ -301,8 +302,7 @@ struct mpic
 #endif
 
 #ifdef CONFIG_PCI_MSI
-       spinlock_t              bitmap_lock;
-       unsigned long           *hwirq_bitmap;
+       struct msi_bitmap       msi_bitmap;
 #endif
 
 #ifdef CONFIG_MPIC_BROKEN_REGREAD
diff --git a/arch/powerpc/include/asm/msi_bitmap.h b/arch/powerpc/include/asm/msi_bitmap.h
new file mode 100644 (file)
index 0000000..97ac3f4
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _POWERPC_SYSDEV_MSI_BITMAP_H
+#define _POWERPC_SYSDEV_MSI_BITMAP_H
+
+/*
+ * Copyright 2008, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/of.h>
+#include <asm/irq.h>
+
+struct msi_bitmap {
+       struct device_node      *of_node;
+       unsigned long           *bitmap;
+       spinlock_t              lock;
+       unsigned int            irq_count;
+};
+
+int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num);
+void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset,
+                           unsigned int num);
+void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq);
+
+int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp);
+
+int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
+                    struct device_node *of_node);
+void msi_bitmap_free(struct msi_bitmap *bmp);
+
+#endif /* _POWERPC_SYSDEV_MSI_BITMAP_H */
index 3c123990ca2e0f3db95b03c939e62a6e6050df30..a64debf177dca8efcbe7534333f81a5b2d3d26d5 100644 (file)
@@ -24,8 +24,5 @@ extern struct of_device *of_device_alloc(struct device_node *np,
 extern int of_device_uevent(struct device *dev,
                            struct kobj_uevent_env *env);
 
-/* This is just here during the transition */
-#include <linux/of_device.h>
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_OF_DEVICE_H */
index 18659ef72139c3599796b5fc718a23fe676bc71d..53b46507ffde02c9baab0c6343cd22ffb76c8092 100644 (file)
@@ -11,9 +11,6 @@
  *
  */
 
-/* This is just here during the transition */
-#include <linux/of_platform.h>
-
 /* Platform drivers register/unregister */
 static inline int of_register_platform_driver(struct of_platform_driver *drv)
 {
index 6493a395508b800678e0df51b4d0d17fb587a2a0..082b3aedf145b4fe3d368f39829cc87911e9b62a 100644 (file)
@@ -62,6 +62,8 @@ struct paca_struct {
        u16 paca_index;                 /* Logical processor number */
 
        u64 kernel_toc;                 /* Kernel TOC address */
+       u64 kernelbase;                 /* Base address of kernel */
+       u64 kernel_msr;                 /* MSR while running in kernel */
        u64 stab_real;                  /* Absolute address of segment table */
        u64 stab_addr;                  /* Virtual address of segment table */
        void *emergency_sp;             /* pointer to emergency stack */
index e088545cb3f5ea67b2065f962f89c34f4798ae1a..64e144505f653e0ae1d4f190690ef458e9aad5e7 100644 (file)
 #define PAGE_OFFSET    ASM_CONST(CONFIG_PAGE_OFFSET)
 #define LOAD_OFFSET    ASM_CONST((CONFIG_KERNEL_START-CONFIG_PHYSICAL_START))
 
-#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_FLATMEM)
+#if defined(CONFIG_RELOCATABLE)
 #ifndef __ASSEMBLY__
 extern phys_addr_t memstart_addr;
 extern phys_addr_t kernstart_addr;
 #endif
 #define PHYSICAL_START kernstart_addr
-#define MEMORY_START   memstart_addr
 #else
 #define PHYSICAL_START ASM_CONST(CONFIG_PHYSICAL_START)
+#endif
+
+#ifdef CONFIG_PPC64
+#define MEMORY_START   0UL
+#elif defined(CONFIG_RELOCATABLE)
+#define MEMORY_START   memstart_addr
+#else
 #define MEMORY_START   (PHYSICAL_START + PAGE_OFFSET - KERNELBASE)
 #endif
 
@@ -92,8 +98,8 @@ extern phys_addr_t kernstart_addr;
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#define __va(x) ((void *)((unsigned long)(x) - PHYSICAL_START + KERNELBASE))
-#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE)
+#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START))
+#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START)
 
 /*
  * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
index ebfae530a3799b075c201df143394d1694ef74e7..d77072a32cc68b2553b1e329542b1f4925656c57 100644 (file)
 #define ARCH_KMALLOC_MINALIGN  L1_CACHE_BYTES
 #endif
 
+#ifdef CONFIG_PTE_64BIT
+#define PTE_FLAGS_OFFSET       4       /* offset of PTE flags, in bytes */
+#else
+#define PTE_FLAGS_OFFSET       0
+#endif
+
 #ifndef __ASSEMBLY__
 /*
  * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
- * physical addressing.  For now this just the IBM PPC440.
+ * physical addressing.
  */
 #ifdef CONFIG_PTE_64BIT
 typedef unsigned long long pte_basic_t;
index a05a942b1c2573d4dae0ba35e2bbf24d6b3d2f14..0e52c7828ea498d48c34a37155dba0f57b39a349 100644 (file)
@@ -60,6 +60,14 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
        return channel ? 15 : 14;
 }
 
+#ifdef CONFIG_PCI
+extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops);
+extern struct dma_mapping_ops *get_pci_dma_ops(void);
+#else  /* CONFIG_PCI */
+#define set_pci_dma_ops(d)
+#define get_pci_dma_ops()      NULL
+#endif
+
 #ifdef CONFIG_PPC64
 
 /*
@@ -70,9 +78,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 #define PCI_DISABLE_MWI
 
 #ifdef CONFIG_PCI
-extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops);
-extern struct dma_mapping_ops *get_pci_dma_ops(void);
-
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
                                        enum pci_dma_burst_strategy *strat,
                                        unsigned long *strategy_parameter)
@@ -89,9 +94,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
        *strat = PCI_DMA_BURST_MULTIPLE;
        *strategy_parameter = cacheline_size;
 }
-#else  /* CONFIG_PCI */
-#define set_pci_dma_ops(d)
-#define get_pci_dma_ops()      NULL
 #endif
 
 #else /* 32-bit */
index 6fe39e327047d16814f345402303efb75e9822b7..6ab7c67cb5ab6355ba453e4832ad55bcdb03ec85 100644 (file)
@@ -261,6 +261,7 @@ extern int icache_44x_need_flush;
 #define _PAGE_HWEXEC   0x00000004              /* H: Execute permission */
 #define _PAGE_ACCESSED 0x00000008              /* S: Page referenced */
 #define _PAGE_DIRTY    0x00000010              /* S: Page dirty */
+#define _PAGE_SPECIAL  0x00000020              /* S: Special page */
 #define _PAGE_USER     0x00000040              /* S: User page */
 #define _PAGE_ENDIAN   0x00000080              /* H: E bit */
 #define _PAGE_GUARDED  0x00000100              /* H: G bit */
@@ -276,6 +277,7 @@ extern int icache_44x_need_flush;
 /* ERPN in a PTE never gets cleared, ignore it */
 #define _PTE_NONE_MASK 0xffffffff00000000ULL
 
+#define __HAVE_ARCH_PTE_SPECIAL
 
 #elif defined(CONFIG_FSL_BOOKE)
 /*
@@ -305,6 +307,7 @@ extern int icache_44x_need_flush;
 #define _PAGE_COHERENT 0x00100 /* H: M bit */
 #define _PAGE_NO_CACHE 0x00200 /* H: I bit */
 #define _PAGE_WRITETHRU        0x00400 /* H: W bit */
+#define _PAGE_SPECIAL  0x00800 /* S: Special page */
 
 #ifdef CONFIG_PTE_64BIT
 /* ERPN in a PTE never gets cleared, ignore it */
@@ -315,6 +318,8 @@ extern int icache_44x_need_flush;
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD       (~PAGE_MASK)
 
+#define __HAVE_ARCH_PTE_SPECIAL
+
 #elif defined(CONFIG_8xx)
 /* Definitions for 8xx embedded chips. */
 #define _PAGE_PRESENT  0x0001  /* Page is valid */
@@ -362,8 +367,14 @@ extern int icache_44x_need_flush;
 #define _PAGE_ACCESSED 0x100   /* R: page referenced */
 #define _PAGE_EXEC     0x200   /* software: i-cache coherency required */
 #define _PAGE_RW       0x400   /* software: user write access allowed */
+#define _PAGE_SPECIAL  0x800   /* software: Special page */
 
+#ifdef CONFIG_PTE_64BIT
+/* We never clear the high word of the pte */
+#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE)
+#else
 #define _PTE_NONE_MASK _PAGE_HASHPTE
+#endif
 
 #define _PMD_PRESENT   0
 #define _PMD_PRESENT_MASK (PAGE_MASK)
@@ -372,6 +383,8 @@ extern int icache_44x_need_flush;
 /* Hash table based platforms need atomic updates of the linux PTE */
 #define PTE_ATOMIC_UPDATES     1
 
+#define __HAVE_ARCH_PTE_SPECIAL
+
 #endif
 
 /*
@@ -404,6 +417,9 @@ extern int icache_44x_need_flush;
 #ifndef _PAGE_WRITETHRU
 #define _PAGE_WRITETHRU        0
 #endif
+#ifndef _PAGE_SPECIAL
+#define _PAGE_SPECIAL  0
+#endif
 #ifndef _PMD_PRESENT_MASK
 #define _PMD_PRESENT_MASK      _PMD_PRESENT
 #endif
@@ -415,11 +431,11 @@ extern int icache_44x_need_flush;
 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 
 
-#define PAGE_PROT_BITS __pgprot(_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
-                                _PAGE_WRITETHRU | _PAGE_ENDIAN | \
-                                _PAGE_USER | _PAGE_ACCESSED | \
-                                _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
-                                _PAGE_EXEC | _PAGE_HWEXEC)
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+                        _PAGE_WRITETHRU | _PAGE_ENDIAN | \
+                        _PAGE_USER | _PAGE_ACCESSED | \
+                        _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
+                        _PAGE_EXEC | _PAGE_HWEXEC)
 /*
  * Note: the _PAGE_COHERENT bit automatically gets set in the hardware
  * PTE if CONFIG_SMP is defined (hash_page does this); there is no need
@@ -517,7 +533,8 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
 
 #define pte_none(pte)          ((pte_val(pte) & ~_PTE_NONE_MASK) == 0)
 #define pte_present(pte)       (pte_val(pte) & _PAGE_PRESENT)
-#define pte_clear(mm,addr,ptep)        do { set_pte_at((mm), (addr), (ptep), __pte(0)); } while (0)
+#define pte_clear(mm, addr, ptep) \
+       do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
 
 #define pmd_none(pmd)          (!pmd_val(pmd))
 #define        pmd_bad(pmd)            (pmd_val(pmd) & _PMD_BAD)
@@ -533,7 +550,7 @@ static inline int pte_write(pte_t pte)              { return pte_val(pte) & _PAGE_RW; }
 static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
 static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
 static inline int pte_file(pte_t pte)          { return pte_val(pte) & _PAGE_FILE; }
-static inline int pte_special(pte_t pte)       { return 0; }
+static inline int pte_special(pte_t pte)       { return pte_val(pte) & _PAGE_SPECIAL; }
 
 static inline void pte_uncache(pte_t pte)       { pte_val(pte) |= _PAGE_NO_CACHE; }
 static inline void pte_cache(pte_t pte)         { pte_val(pte) &= ~_PAGE_NO_CACHE; }
@@ -552,10 +569,10 @@ static inline pte_t pte_mkdirty(pte_t pte) {
 static inline pte_t pte_mkyoung(pte_t pte) {
        pte_val(pte) |= _PAGE_ACCESSED; return pte; }
 static inline pte_t pte_mkspecial(pte_t pte) {
-       return pte; }
-static inline unsigned long pte_pgprot(pte_t pte)
+       pte_val(pte) |= _PAGE_SPECIAL; return pte; }
+static inline pgprot_t pte_pgprot(pte_t pte)
 {
-       return __pgprot(pte_val(pte)) & PAGE_PROT_BITS;
+       return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
 }
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
@@ -575,6 +592,10 @@ extern int flush_hash_pages(unsigned context, unsigned long va,
 extern void add_hash_page(unsigned context, unsigned long va,
                          unsigned long pmdval);
 
+/* Flush an entry from the TLB/hash table */
+extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
+                            unsigned long address);
+
 /*
  * Atomic PTE updates.
  *
@@ -612,9 +633,6 @@ static inline unsigned long pte_update(pte_t *p,
        return old;
 }
 #else /* CONFIG_PTE_64BIT */
-/* TODO: Change that to only modify the low word and move set_pte_at()
- * out of line
- */
 static inline unsigned long long pte_update(pte_t *p,
                                            unsigned long clr,
                                            unsigned long set)
@@ -652,14 +670,36 @@ static inline unsigned long long pte_update(pte_t *p,
  * On machines which use an MMU hash table we avoid changing the
  * _PAGE_HASHPTE bit.
  */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep, pte_t pte)
 {
-#if _PAGE_HASHPTE != 0
+#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
        pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
+#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
+#if _PAGE_HASHPTE != 0
+       if (pte_val(*ptep) & _PAGE_HASHPTE)
+               flush_hash_entry(mm, ptep, addr);
+#endif
+       __asm__ __volatile__("\
+               stw%U0%X0 %2,%0\n\
+               eieio\n\
+               stw%U0%X0 %L2,%1"
+       : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+       : "r" (pte) : "memory");
 #else
-       *ptep = pte;
+       *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+                     | (pte_val(pte) & ~_PAGE_HASHPTE));
+#endif
+}
+
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep, pte_t pte)
+{
+#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
+       WARN_ON(pte_present(*ptep));
 #endif
+       __set_pte_at(mm, addr, ptep, pte);
 }
 
 /*
index 4597c491e9b52ee72c854271a88e0b572823507a..4c0a8c62859d0f6d1560c2b575ecc85cfc219831 100644 (file)
 #define PAGE_AGP       __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
 #define HAVE_PAGE_AGP
 
-#define PAGE_PROT_BITS __pgprot(_PAGE_GUARDED | _PAGE_COHERENT | \
-                                _PAGE_NO_CACHE | _PAGE_WRITETHRU | \
-                                _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER | \
-                                _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC)
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | \
+                        _PAGE_NO_CACHE | _PAGE_WRITETHRU |             \
+                        _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER |         \
+                        _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC)
 /* PTEIDX nibble */
 #define _PTEIDX_SECONDARY      0x8
 #define _PTEIDX_GROUP_IX       0x7
@@ -264,9 +264,9 @@ static inline pte_t pte_mkhuge(pte_t pte) {
        return pte; }
 static inline pte_t pte_mkspecial(pte_t pte) {
        pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline unsigned long pte_pgprot(pte_t pte)
+static inline pgprot_t pte_pgprot(pte_t pte)
 {
-       return __pgprot(pte_val(pte)) & PAGE_PROT_BITS;
+       return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
 }
 
 /* Atomic PTE updates */
index 0966899d974b07050e79003c1d50eb267dbb1b6e..c4a029ccb4d31d5273cc6e43fc381e23ff6f9c08 100644 (file)
@@ -268,7 +268,7 @@ n:
  *   Loads the value of the constant expression 'expr' into register 'rn'
  *   using immediate instructions only.  Use this when it's important not
  *   to reference other data (i.e. on ppc64 when the TOC pointer is not
- *   valid).
+ *   valid) and when 'expr' is a constant or absolute address.
  *
  * LOAD_REG_ADDR(rn, name)
  *   Loads the address of label 'name' into register 'rn'.  Use this when
index be980f4ee4956cd20d00fe107c103d7b2a58d21a..67453766bff1f7b6593fb1c3e75aca686e4c23c6 100644 (file)
 #define SPRN_EVPR      0x3D6   /* Exception Vector Prefix Register */
 #define SPRN_L1CSR0    0x3F2   /* L1 Cache Control and Status Register 0 */
 #define SPRN_L1CSR1    0x3F3   /* L1 Cache Control and Status Register 1 */
+#define SPRN_MMUCSR0   0x3F4   /* MMU Control and Status Register 0 */
 #define SPRN_PIT       0x3DB   /* Programmable Interval Timer */
 #define SPRN_BUCSR     0x3F5   /* Branch Unit Control and Status */
 #define SPRN_L2CSR0    0x3F9   /* L2 Data Cache Control and Status Register 0 */
 #define L2CSR0_L2LOA   0x00000080      /* L2 Cache Lock Overflow Allocate */
 #define L2CSR0_L2LO    0x00000020      /* L2 Cache Lock Overflow */
 
+/* Bit definitions for MMUCSR0 */
+#define MMUCSR0_TLB1FI 0x00000002      /* TLB1 Flash invalidate */
+#define MMUCSR0_TLB0FI 0x00000004      /* TLB0 Flash invalidate */
+#define MMUCSR0_TLB2FI 0x00000040      /* TLB2 Flash invalidate */
+#define MMUCSR0_TLB3FI 0x00000020      /* TLB3 Flash invalidate */
+
 /* Bit definitions for SGR. */
 #define SGR_NORMAL     0               /* Speculative fetching allowed. */
 #define SGR_GUARDED    1               /* Speculative fetching disallowed. */
index 07956f3e78444f5f63390d8d328c000af957061f..6fbce725c710f97453079205e190c02c7365cd0b 100644 (file)
@@ -18,6 +18,12 @@ static inline int in_kernel_text(unsigned long addr)
        return 0;
 }
 
+static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
+{
+       return start < (unsigned long)__init_end &&
+               (unsigned long)_stext < end;
+}
+
 #undef dereference_function_descriptor
 static inline void *dereference_function_descriptor(void *ptr)
 {
similarity index 83%
rename from arch/powerpc/math-emu/sfp-machine.h
rename to arch/powerpc/include/asm/sfp-machine.h
index 4b17d83cfcdd616dd1ac043d51f7c59f3909b7cc..ced34f1dc8f814ce0a79a691ef67297220510f40 100644 (file)
  * #define _FP_DIV_MEAT_D(R,X,Y)   _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
  */
 
-#define _FP_MUL_MEAT_S(R,X,Y)   _FP_MUL_MEAT_1_wide(S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y)   _FP_MUL_MEAT_2_wide(D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_S(R,X,Y)   _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)   _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
 
-#define _FP_DIV_MEAT_S(R,X,Y)   _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y)   _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
 
 /* These macros define what NaN looks like. They're supposed to expand to
  * a comma-separated set of 32bit unsigned ints that encode NaN.
  */
-#define _FP_NANFRAC_S          _FP_QNANBIT_S
-#define _FP_NANFRAC_D          _FP_QNANBIT_D, 0
-#define _FP_NANFRAC_Q           _FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
 
 #define _FP_KEEPNANFRACP 1
 
+/* Exception flags.  We use the bit positions of the appropriate bits
+   in the FPSCR, which also correspond to the FE_* bits.  This makes
+   everything easier ;-).  */
+#define FP_EX_INVALID         (1 << (31 - 2))
+#define FP_EX_INVALID_SNAN     EFLAG_VXSNAN
+#define FP_EX_INVALID_ISI      EFLAG_VXISI
+#define FP_EX_INVALID_IDI      EFLAG_VXIDI
+#define FP_EX_INVALID_ZDZ      EFLAG_VXZDZ
+#define FP_EX_INVALID_IMZ      EFLAG_VXIMZ
+#define FP_EX_OVERFLOW        (1 << (31 - 3))
+#define FP_EX_UNDERFLOW       (1 << (31 - 4))
+#define FP_EX_DIVZERO         (1 << (31 - 5))
+#define FP_EX_INEXACT         (1 << (31 - 6))
+
 /* This macro appears to be called when both X and Y are NaNs, and
  * has to choose one and copy it to R. i386 goes for the larger of the
  * two, sparc64 just picks Y. I don't understand this at all so I'll
  * go with sparc64 because it's shorter :->   -- PMM
  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y)                 \
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)             \
   do {                                                 \
     R##_s = Y##_s;                                     \
     _FP_FRAC_COPY_##wc(R,Y);                           \
   } while (0)
 
 
-extern void fp_unpack_d(long *, unsigned long *, unsigned long *,
-                       long *, long *, void *);
-extern int  fp_pack_d(void *, long, unsigned long, unsigned long, long, long);
-extern int  fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
-
-#define __FP_UNPACK_RAW_1(fs, X, val)                  \
-  do {                                                 \
-    union _FP_UNION_##fs *_flo =                       \
-       (union _FP_UNION_##fs *)val;                    \
-                                                       \
-    X##_f = _flo->bits.frac;                           \
-    X##_e = _flo->bits.exp;                            \
-    X##_s = _flo->bits.sign;                           \
-  } while (0)
-
-#define __FP_UNPACK_RAW_2(fs, X, val)                  \
-  do {                                                 \
-    union _FP_UNION_##fs *_flo =                       \
-       (union _FP_UNION_##fs *)val;                    \
-                                                       \
-    X##_f0 = _flo->bits.frac0;                         \
-    X##_f1 = _flo->bits.frac1;                         \
-    X##_e  = _flo->bits.exp;                           \
-    X##_s  = _flo->bits.sign;                          \
-  } while (0)
-
-#define __FP_UNPACK_S(X,val)           \
-  do {                                 \
-    __FP_UNPACK_RAW_1(S,X,val);                \
-    _FP_UNPACK_CANONICAL(S,1,X);       \
-  } while (0)
-
-#define __FP_UNPACK_D(X,val)           \
-       fp_unpack_d(&X##_s, &X##_f1, &X##_f0, &X##_e, &X##_c, val)
-
-#define __FP_PACK_RAW_1(fs, val, X)                    \
-  do {                                                 \
-    union _FP_UNION_##fs *_flo =                       \
-       (union _FP_UNION_##fs *)val;                    \
-                                                       \
-    _flo->bits.frac = X##_f;                           \
-    _flo->bits.exp  = X##_e;                           \
-    _flo->bits.sign = X##_s;                           \
-  } while (0)
-
-#define __FP_PACK_RAW_2(fs, val, X)                    \
-  do {                                                 \
-    union _FP_UNION_##fs *_flo =                       \
-       (union _FP_UNION_##fs *)val;                    \
-                                                       \
-    _flo->bits.frac0 = X##_f0;                         \
-    _flo->bits.frac1 = X##_f1;                         \
-    _flo->bits.exp   = X##_e;                          \
-    _flo->bits.sign  = X##_s;                          \
-  } while (0)
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
@@ -182,15 +143,30 @@ extern int  fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
 #define __FP_PACK_S(val,X)                     \
 ({  int __exc = _FP_PACK_CANONICAL(S,1,X);     \
     if(!__exc || !__FPU_TRAP_P(__exc))         \
-        __FP_PACK_RAW_1(S,val,X);              \
+        _FP_PACK_RAW_1_P(S,val,X);             \
     __exc;                                     \
 })
 
 #define __FP_PACK_D(val,X)                     \
-       fp_pack_d(val, X##_s, X##_f1, X##_f0, X##_e, X##_c)
-
-#define __FP_PACK_DS(val,X)                    \
-       fp_pack_ds(val, X##_s, X##_f1, X##_f0, X##_e, X##_c)
+   do {                                                                        \
+       _FP_PACK_CANONICAL(D, 2, X);                                    \
+       if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS))     \
+               _FP_PACK_RAW_2_P(D, val, X);                            \
+   } while (0)
+
+#define __FP_PACK_DS(val,X)                                                    \
+   do {                                                                                \
+          FP_DECL_S(__X);                                                      \
+          FP_CONV(S, D, 1, 2, __X, X);                                         \
+          _FP_PACK_CANONICAL(S, 1, __X);                                       \
+          if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) {        \
+                  _FP_UNPACK_CANONICAL(S, 1, __X);                             \
+                  FP_CONV(D, S, 2, 1, X, __X);                                 \
+                  _FP_PACK_CANONICAL(D, 2, X);                                 \
+                  if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS))  \
+                  _FP_PACK_RAW_2_P(D, val, X);                                 \
+          }                                                                    \
+   } while (0)
 
 /* Obtain the current rounding mode. */
 #define FP_ROUNDMODE                   \
index 4d28e1e4521b8c39992d327a4d0699d8f0df4ba2..1866cec4f9677b5fc995e754cea3ed6936d7ec57 100644 (file)
@@ -56,9 +56,16 @@ extern int smp_hw_index[];
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 #define hard_smp_processor_id()        (smp_hw_index[smp_processor_id()])
-#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)])
-#define set_hard_smp_processor_id(cpu, phys)\
-                                       (smp_hw_index[(cpu)] = (phys))
+
+static inline int get_hard_smp_processor_id(int cpu)
+{
+       return smp_hw_index[cpu];
+}
+
+static inline void set_hard_smp_processor_id(int cpu, int phys)
+{
+       smp_hw_index[cpu] = phys;
+}
 #endif
 
 DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
@@ -86,15 +93,21 @@ extern void __cpu_die(unsigned int cpu);
 
 #else
 /* for UP */
-#define hard_smp_processor_id()                0
+#define hard_smp_processor_id()                get_hard_smp_processor_id(0)
 #define smp_setup_cpu_maps()
 
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_PPC64
-#define get_hard_smp_processor_id(CPU) (paca[(CPU)].hw_cpu_id)
-#define set_hard_smp_processor_id(CPU, VAL) \
-       do { (paca[(CPU)].hw_cpu_id = (VAL)); } while (0)
+static inline int get_hard_smp_processor_id(int cpu)
+{
+       return paca[cpu].hw_cpu_id;
+}
+
+static inline void set_hard_smp_processor_id(int cpu, int phys)
+{
+       paca[cpu].hw_cpu_id = phys;
+}
 
 extern void smp_release_cpus(void);
 
@@ -102,10 +115,17 @@ extern void smp_release_cpus(void);
 /* 32-bit */
 #ifndef CONFIG_SMP
 extern int boot_cpuid_phys;
-#define get_hard_smp_processor_id(cpu)         boot_cpuid_phys
-#define set_hard_smp_processor_id(cpu, phys)
-#endif
-#endif
+static inline int get_hard_smp_processor_id(int cpu)
+{
+       return boot_cpuid_phys;
+}
+
+static inline void set_hard_smp_processor_id(int cpu, int phys)
+{
+       boot_cpuid_phys = phys;
+}
+#endif /* !CONFIG_SMP */
+#endif /* !CONFIG_PPC64 */
 
 extern int smt_enabled_at_boot;
 
index f6cc7a43b4faadeb17f080794ff7e8d2a06f4a72..803def236654a0e81b4e6ab105e994e63fb164a4 100644 (file)
@@ -32,7 +32,7 @@ COMPAT_SYS_SPU(stime)
 COMPAT_SYS(ptrace)
 SYSCALL_SPU(alarm)
 OLDSYS(fstat)
-COMPAT_SYS(pause)
+SYSCALL(pause)
 COMPAT_SYS(utime)
 SYSCALL(ni_syscall)
 SYSCALL(ni_syscall)
index 361cd5c7a32b428107b6815ae2240fce19de99e1..a2c6bfd85fb7a38ab6d002373c24afbf8648399a 100644 (file)
@@ -29,6 +29,9 @@
 #include <linux/mm.h>
 
 extern void _tlbie(unsigned long address, unsigned int pid);
+extern void _tlbil_all(void);
+extern void _tlbil_pid(unsigned int pid);
+extern void _tlbil_va(unsigned long address, unsigned int pid);
 
 #if defined(CONFIG_40x) || defined(CONFIG_8xx)
 #define _tlbia()       asm volatile ("tlbia; sync" : : : "memory")
@@ -38,31 +41,31 @@ extern void _tlbia(void);
 
 static inline void flush_tlb_mm(struct mm_struct *mm)
 {
-       _tlbia();
+       _tlbil_pid(mm->context.id);
 }
 
 static inline void flush_tlb_page(struct vm_area_struct *vma,
                                  unsigned long vmaddr)
 {
-       _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0);
+       _tlbil_va(vmaddr, vma ? vma->vm_mm->context.id : 0);
 }
 
 static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
                                         unsigned long vmaddr)
 {
-       _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0);
+       flush_tlb_page(vma, vmaddr);
 }
 
 static inline void flush_tlb_range(struct vm_area_struct *vma,
                                   unsigned long start, unsigned long end)
 {
-       _tlbia();
+       _tlbil_pid(vma->vm_mm->context.id);
 }
 
 static inline void flush_tlb_kernel_range(unsigned long start,
                                          unsigned long end)
 {
-       _tlbia();
+       _tlbil_pid(0);
 }
 
 #elif defined(CONFIG_PPC32)
index c646f34c4e8b5879d1c4c4922b40bf43191f0445..c004c13f291e771fa63a6f842094b3faacee7037 100644 (file)
@@ -48,7 +48,7 @@ typedef struct {
 
 typedef __vector128 vector128;
 
-#ifdef __powerpc64__
+#if defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)
 typedef u64 dma_addr_t;
 #else
 typedef u32 dma_addr_t;
diff --git a/arch/powerpc/kernel/.gitignore b/arch/powerpc/kernel/.gitignore
new file mode 100644 (file)
index 0000000..c5f676c
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.lds
index 946daea780f1ea6858624368e235142f0448a508..fdb58253fa5b15727580cdc2119eef4512596411 100644 (file)
@@ -28,13 +28,14 @@ endif
 obj-y                          := cputable.o ptrace.o syscalls.o \
                                   irq.o align.o signal_32.o pmc.o vdso.o \
                                   init_task.o process.o systbl.o idle.o \
-                                  signal.o
+                                  signal.o sysfs.o
 obj-y                          += vdso32/
 obj-$(CONFIG_PPC64)            += setup_64.o sys_ppc32.o \
                                   signal_64.o ptrace32.o \
                                   paca.o cpu_setup_ppc970.o \
                                   cpu_setup_pa6t.o \
-                                  firmware.o sysfs.o nvram_64.o
+                                  firmware.o nvram_64.o
+obj64-$(CONFIG_RELOCATABLE)    += reloc_64.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.o
 obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
@@ -69,10 +70,10 @@ extra-$(CONFIG_8xx)         := head_8xx.o
 extra-y                                += vmlinux.lds
 
 obj-y                          += time.o prom.o traps.o setup-common.o \
-                                  udbg.o misc.o io.o \
+                                  udbg.o misc.o io.o dma.o \
                                   misc_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC32)            += entry_32.o setup_32.o
-obj-$(CONFIG_PPC64)            += dma_64.o iommu.o
+obj-$(CONFIG_PPC64)            += dma-iommu.o iommu.o
 obj-$(CONFIG_KGDB)             += kgdb.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)        += prom_init.o
 obj-$(CONFIG_MODULES)          += ppc_ksyms.o
index 92768d3006f7c0800c263bd2d121537fba2a4409..09febc582584c1a662568610cf542bf3b4759d5e 100644 (file)
@@ -122,6 +122,8 @@ int main(void)
        DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
        DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
        DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
+       DEFINE(PACAKBASE, offsetof(struct paca_struct, kernelbase));
+       DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
        DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
        DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
        DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
@@ -350,6 +352,7 @@ int main(void)
 #endif
 
        DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE);
+       DEFINE(PTE_SIZE, sizeof(pte_t));
 
 #ifdef CONFIG_KVM
        DEFINE(TLBE_BYTES, sizeof(struct tlbe));
index d8f0329b13444b73be463ea06c71169a193d180f..26e58630ed7bf3d2f618abae3f6a74d7f4350e4b 100644 (file)
@@ -442,28 +442,26 @@ void btext_drawtext(const char *c, unsigned int len)
 
 void btext_drawhex(unsigned long v)
 {
-       char *hex_table = "0123456789abcdef";
-
        if (!boot_text_mapped)
                return;
 #ifdef CONFIG_PPC64
-       btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
+       btext_drawchar(hex_asc_hi(v >> 56));
+       btext_drawchar(hex_asc_lo(v >> 56));
+       btext_drawchar(hex_asc_hi(v >> 48));
+       btext_drawchar(hex_asc_lo(v >> 48));
+       btext_drawchar(hex_asc_hi(v >> 40));
+       btext_drawchar(hex_asc_lo(v >> 40));
+       btext_drawchar(hex_asc_hi(v >> 32));
+       btext_drawchar(hex_asc_lo(v >> 32));
 #endif
-       btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >>  8) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >>  4) & 0x0000000FUL]);
-       btext_drawchar(hex_table[(v >>  0) & 0x0000000FUL]);
+       btext_drawchar(hex_asc_hi(v >> 24));
+       btext_drawchar(hex_asc_lo(v >> 24));
+       btext_drawchar(hex_asc_hi(v >> 16));
+       btext_drawchar(hex_asc_lo(v >> 16));
+       btext_drawchar(hex_asc_hi(v >> 8));
+       btext_drawchar(hex_asc_lo(v >> 8));
+       btext_drawchar(hex_asc_hi(v));
+       btext_drawchar(hex_asc_lo(v));
        btext_drawchar(' ');
 }
 
index bf118c3857520a81eb978b016512607f49c8b611..27f2507279d830571fcecd0aa4e13c8a41d81062 100644 (file)
@@ -110,7 +110,7 @@ load_hids:
        isync
 
        /* Save away cpu state */
-       LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
+       LOAD_REG_ADDR(r5,cpu_state_storage)
 
        /* Save HID0,1,4 and 5 */
        mfspr   r3,SPRN_HID0
@@ -134,7 +134,7 @@ _GLOBAL(__restore_cpu_ppc970)
        rldicl. r0,r0,4,63
        beqlr
 
-       LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
+       LOAD_REG_ADDR(r5,cpu_state_storage)
        /* Before accessing memory, we make sure rm_ci is clear */
        li      r0,0
        mfspr   r3,SPRN_HID4
index 25c273c761d19855f2d8861720c24f7cb095bb2f..e70d0483fb4e55494c87f4d97d33b120336deed0 100644 (file)
@@ -610,6 +610,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750cx,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -623,6 +624,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750cx,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -636,6 +638,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750cx,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -649,6 +652,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -662,6 +666,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -675,6 +680,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -688,6 +694,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -701,6 +708,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750fx,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -714,6 +722,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750fx,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -727,6 +736,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_IBM,
                .cpu_setup              = __setup_cpu_750,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
@@ -741,6 +751,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_7400,
                .machine_check          = machine_check_generic,
                .platform               = "ppc7400",
@@ -755,6 +766,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_7400,
                .machine_check          = machine_check_generic,
                .platform               = "ppc7400",
@@ -769,6 +781,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_7410,
                .machine_check          = machine_check_generic,
                .platform               = "ppc7400",
@@ -783,6 +796,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -799,6 +813,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -815,6 +830,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -831,6 +847,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -847,6 +864,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -863,6 +881,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -879,6 +898,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -895,6 +915,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -910,6 +931,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -926,6 +948,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
@@ -942,6 +965,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_G4,
                .cpu_setup              = __setup_cpu_745x,
                .oprofile_cpu_type      = "ppc/7450",
                .oprofile_type          = PPC_OPROFILE_G4,
similarity index 53%
rename from arch/powerpc/kernel/dma_64.c
rename to arch/powerpc/kernel/dma-iommu.c
index ae5708e3a3127fc9a180ae1d881d5bea5ede48bc..49248f89ce23b19c6b57a04c32e6c36d8ac31e9d 100644 (file)
@@ -2,14 +2,10 @@
  * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
  *
  * Provide default implementations of the DMA mapping callbacks for
- * directly mapped busses and busses using the iommu infrastructure
+ * busses using the iommu infrastructure
  */
 
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <asm/bug.h>
 #include <asm/iommu.h>
-#include <asm/abs_addr.h>
 
 /*
  * Generic iommu implementation
@@ -24,7 +20,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
 {
        return iommu_alloc_coherent(dev, dev->archdata.dma_data, size,
                                    dma_handle, device_to_mask(dev), flag,
-                                   dev->archdata.numa_node);
+                                   dev_to_node(dev));
 }
 
 static void dma_iommu_free_coherent(struct device *dev, size_t size,
@@ -105,96 +101,3 @@ struct dma_mapping_ops dma_iommu_ops = {
        .dma_supported  = dma_iommu_dma_supported,
 };
 EXPORT_SYMBOL(dma_iommu_ops);
-
-/*
- * Generic direct DMA implementation
- *
- * This implementation supports a per-device offset that can be applied if
- * the address at which memory is visible to devices is not 0. Platform code
- * can set archdata.dma_data to an unsigned long holding the offset. By
- * default the offset is zero.
- */
-
-static unsigned long get_dma_direct_offset(struct device *dev)
-{
-       return (unsigned long)dev->archdata.dma_data;
-}
-
-static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-                                      dma_addr_t *dma_handle, gfp_t flag)
-{
-       struct page *page;
-       void *ret;
-       int node = dev->archdata.numa_node;
-
-       page = alloc_pages_node(node, flag, get_order(size));
-       if (page == NULL)
-               return NULL;
-       ret = page_address(page);
-       memset(ret, 0, size);
-       *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
-
-       return ret;
-}
-
-static void dma_direct_free_coherent(struct device *dev, size_t size,
-                                    void *vaddr, dma_addr_t dma_handle)
-{
-       free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
-                                       size_t size,
-                                       enum dma_data_direction direction,
-                                       struct dma_attrs *attrs)
-{
-       return virt_to_abs(ptr) + get_dma_direct_offset(dev);
-}
-
-static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
-                                   size_t size,
-                                   enum dma_data_direction direction,
-                                   struct dma_attrs *attrs)
-{
-}
-
-static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
-                            int nents, enum dma_data_direction direction,
-                            struct dma_attrs *attrs)
-{
-       struct scatterlist *sg;
-       int i;
-
-       for_each_sg(sgl, sg, nents, i) {
-               sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
-               sg->dma_length = sg->length;
-       }
-
-       return nents;
-}
-
-static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
-                               int nents, enum dma_data_direction direction,
-                               struct dma_attrs *attrs)
-{
-}
-
-static int dma_direct_dma_supported(struct device *dev, u64 mask)
-{
-       /* Could be improved to check for memory though it better be
-        * done via some global so platforms can set the limit in case
-        * they have limited DMA windows
-        */
-       return mask >= DMA_32BIT_MASK;
-}
-
-struct dma_mapping_ops dma_direct_ops = {
-       .alloc_coherent = dma_direct_alloc_coherent,
-       .free_coherent  = dma_direct_free_coherent,
-       .map_single     = dma_direct_map_single,
-       .unmap_single   = dma_direct_unmap_single,
-       .map_sg         = dma_direct_map_sg,
-       .unmap_sg       = dma_direct_unmap_sg,
-       .dma_supported  = dma_direct_dma_supported,
-};
-EXPORT_SYMBOL(dma_direct_ops);
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
new file mode 100644 (file)
index 0000000..1562daf
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
+ *
+ * Provide default implementations of the DMA mapping callbacks for
+ * directly mapped busses.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <asm/bug.h>
+#include <asm/abs_addr.h>
+
+/*
+ * Generic direct DMA implementation
+ *
+ * This implementation supports a per-device offset that can be applied if
+ * the address at which memory is visible to devices is not 0. Platform code
+ * can set archdata.dma_data to an unsigned long holding the offset. By
+ * default the offset is PCI_DRAM_OFFSET.
+ */
+
+static unsigned long get_dma_direct_offset(struct device *dev)
+{
+       if (dev)
+               return (unsigned long)dev->archdata.dma_data;
+
+       return PCI_DRAM_OFFSET;
+}
+
+void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, gfp_t flag)
+{
+       void *ret;
+#ifdef CONFIG_NOT_COHERENT_CACHE
+       ret = __dma_alloc_coherent(size, dma_handle, flag);
+       if (ret == NULL)
+               return NULL;
+       *dma_handle += get_dma_direct_offset(dev);
+       return ret;
+#else
+       struct page *page;
+       int node = dev_to_node(dev);
+
+       /* ignore region specifiers */
+       flag  &= ~(__GFP_HIGHMEM);
+
+       page = alloc_pages_node(node, flag, get_order(size));
+       if (page == NULL)
+               return NULL;
+       ret = page_address(page);
+       memset(ret, 0, size);
+       *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
+
+       return ret;
+#endif
+}
+
+void dma_direct_free_coherent(struct device *dev, size_t size,
+                             void *vaddr, dma_addr_t dma_handle)
+{
+#ifdef CONFIG_NOT_COHERENT_CACHE
+       __dma_free_coherent(size, vaddr);
+#else
+       free_pages((unsigned long)vaddr, get_order(size));
+#endif
+}
+
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+                            int nents, enum dma_data_direction direction,
+                            struct dma_attrs *attrs)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sgl, sg, nents, i) {
+               sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
+               sg->dma_length = sg->length;
+       }
+
+       return nents;
+}
+
+static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction direction,
+                               struct dma_attrs *attrs)
+{
+}
+
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_PPC64
+       /* Could be improved to check for memory though it better be
+        * done via some global so platforms can set the limit in case
+        * they have limited DMA windows
+        */
+       return mask >= DMA_32BIT_MASK;
+#else
+       return 1;
+#endif
+}
+
+static inline dma_addr_t dma_direct_map_page(struct device *dev,
+                                            struct page *page,
+                                            unsigned long offset,
+                                            size_t size,
+                                            enum dma_data_direction dir,
+                                            struct dma_attrs *attrs)
+{
+       BUG_ON(dir == DMA_NONE);
+       __dma_sync_page(page, offset, size, dir);
+       return page_to_phys(page) + offset + get_dma_direct_offset(dev);
+}
+
+static inline void dma_direct_unmap_page(struct device *dev,
+                                        dma_addr_t dma_address,
+                                        size_t size,
+                                        enum dma_data_direction direction,
+                                        struct dma_attrs *attrs)
+{
+}
+
+struct dma_mapping_ops dma_direct_ops = {
+       .alloc_coherent = dma_direct_alloc_coherent,
+       .free_coherent  = dma_direct_free_coherent,
+       .map_sg         = dma_direct_map_sg,
+       .unmap_sg       = dma_direct_unmap_sg,
+       .dma_supported  = dma_direct_dma_supported,
+       .map_page       = dma_direct_map_page,
+       .unmap_page     = dma_direct_unmap_page,
+};
+EXPORT_SYMBOL(dma_direct_ops);
index 2d802e97097c55056757fab95a86aa400f352d99..fd8b4bae9b04e2926277f7dc9945358f8eeed7a8 100644 (file)
@@ -512,31 +512,12 @@ _GLOBAL(ret_from_except_lite)
 #endif
 
 restore:
-       ld      r5,SOFTE(r1)
-#ifdef CONFIG_PPC_ISERIES
 BEGIN_FW_FTR_SECTION
-       cmpdi   0,r5,0
-       beq     4f
-       /* Check for pending interrupts (iSeries) */
-       ld      r3,PACALPPACAPTR(r13)
-       ld      r3,LPPACAANYINT(r3)
-       cmpdi   r3,0
-       beq+    4f                      /* skip do_IRQ if no interrupts */
-
-       li      r3,0
-       stb     r3,PACASOFTIRQEN(r13)   /* ensure we are soft-disabled */
-#ifdef CONFIG_TRACE_IRQFLAGS
-       bl      .trace_hardirqs_off
-       mfmsr   r10
-#endif
-       ori     r10,r10,MSR_EE
-       mtmsrd  r10                     /* hard-enable again */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_IRQ
-       b       .ret_from_except_lite           /* loop back and handle more */
-4:
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif
+       ld      r5,SOFTE(r1)
+FW_FTR_SECTION_ELSE
+       b       iseries_check_pending_irqs
+ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
+2:
        TRACE_AND_RESTORE_IRQ(r5);
 
        /* extract EE bit and use it to restore paca->hard_enabled */
@@ -592,6 +573,30 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
        rfid
        b       .       /* prevent speculative execution */
 
+iseries_check_pending_irqs:
+#ifdef CONFIG_PPC_ISERIES
+       ld      r5,SOFTE(r1)
+       cmpdi   0,r5,0
+       beq     2b
+       /* Check for pending interrupts (iSeries) */
+       ld      r3,PACALPPACAPTR(r13)
+       ld      r3,LPPACAANYINT(r3)
+       cmpdi   r3,0
+       beq+    2b                      /* skip do_IRQ if no interrupts */
+
+       li      r3,0
+       stb     r3,PACASOFTIRQEN(r13)   /* ensure we are soft-disabled */
+#ifdef CONFIG_TRACE_IRQFLAGS
+       bl      .trace_hardirqs_off
+       mfmsr   r10
+#endif
+       ori     r10,r10,MSR_EE
+       mtmsrd  r10                     /* hard-enable again */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_IRQ
+       b       .ret_from_except_lite           /* loop back and handle more */
+#endif
+
 do_work:
 #ifdef CONFIG_PREEMPT
        andi.   r0,r3,MSR_PR    /* Returning to user mode? */
@@ -685,10 +690,6 @@ _GLOBAL(enter_rtas)
        std     r7,_DAR(r1)
        mfdsisr r8
        std     r8,_DSISR(r1)
-       mfsrr0  r9
-       std     r9,_SRR0(r1)
-       mfsrr1  r10
-       std     r10,_SRR1(r1)
 
        /* Temporary workaround to clear CR until RTAS can be modified to
         * ignore all bits.
@@ -749,6 +750,10 @@ _STATIC(rtas_return_loc)
        mfspr   r4,SPRN_SPRG3           /* Get PACA */
        clrldi  r4,r4,2                 /* convert to realmode address */
 
+       bcl     20,31,$+4
+0:     mflr    r3
+       ld      r3,(1f-0b)(r3)          /* get &.rtas_restore_regs */
+
        mfmsr   r6
        li      r0,MSR_RI
        andc    r6,r6,r0
@@ -756,7 +761,6 @@ _STATIC(rtas_return_loc)
        mtmsrd  r6
         
         ld     r1,PACAR1(r4)           /* Restore our SP */
-       LOAD_REG_IMMEDIATE(r3,.rtas_restore_regs)
         ld     r4,PACASAVEDMSR(r4)     /* Restore our MSR */
 
        mtspr   SPRN_SRR0,r3
@@ -764,6 +768,9 @@ _STATIC(rtas_return_loc)
        rfid
        b       .       /* prevent speculative execution */
 
+       .align  3
+1:     .llong  .rtas_restore_regs
+
 _STATIC(rtas_restore_regs)
        /* relocation is on at this point */
        REST_GPR(2, r1)                 /* Restore the TOC */
@@ -783,10 +790,6 @@ _STATIC(rtas_restore_regs)
        mtdar   r7
        ld      r8,_DSISR(r1)
        mtdsisr r8
-       ld      r9,_SRR0(r1)
-       mtsrr0  r9
-       ld      r10,_SRR1(r1)
-       mtsrr1  r10
 
         addi   r1,r1,RTAS_FRAME_SIZE   /* Unstack our frame */
        ld      r0,16(r1)               /* get return address */
index 8bb65751929948fbc35e29fce9fb899058d9b39a..0c326823c6d4caf088663efd2c68804c6696d983 100644 (file)
@@ -110,6 +110,12 @@ __start:
 #ifdef CONFIG_PPC_MULTIPLATFORM
        cmpwi   0,r5,0
        beq     1f
+
+       /* find out where we are now */
+       bcl     20,31,$+4
+0:     mflr    r8                      /* r8 = runtime addr here */
+       addis   r8,r8,(_stext - 0b)@ha
+       addi    r8,r8,(_stext - 0b)@l   /* current runtime base addr */
        bl      prom_init
        trap
 #endif
@@ -369,13 +375,13 @@ i##n:                                                             \
 DataAccess:
        EXCEPTION_PROLOG
        mfspr   r10,SPRN_DSISR
+       stw     r10,_DSISR(r11)
        andis.  r0,r10,0xa470           /* weird error? */
        bne     1f                      /* if not, try to put a PTE */
        mfspr   r4,SPRN_DAR             /* into the hash table */
        rlwinm  r3,r10,32-15,21,21      /* DSISR_STORE -> _PAGE_RW */
        bl      hash_page
-1:     stw     r10,_DSISR(r11)
-       mr      r5,r10
+1:     lwz     r5,_DSISR(r11)          /* get DSISR value */
        mfspr   r4,SPRN_DAR
        EXC_XFER_EE_LITE(0x300, handle_page_fault)
 
index cc8fb474d5204ed3c2cf2c48bd754b1fdf3758c9..84856bee33a54a5bc58d7c99edf67286ddd281e0 100644 (file)
@@ -82,7 +82,11 @@ END_FTR_SECTION(0, 1)
        /* Catch branch to 0 in real mode */
        trap
 
-       /* Secondary processors spin on this value until it goes to 1. */
+       /* Secondary processors spin on this value until it becomes nonzero.
+        * When it does it contains the real address of the descriptor
+        * of the function that the cpu should jump to to continue
+        * initialization.
+        */
        .globl  __secondary_hold_spinloop
 __secondary_hold_spinloop:
        .llong  0x0
@@ -109,8 +113,11 @@ __secondary_hold_acknowledge:
  * before the bulk of the kernel has been relocated.  This code
  * is relocated to physical address 0x60 before prom_init is run.
  * All of it must fit below the first exception vector at 0x100.
+ * Use .globl here not _GLOBAL because we want __secondary_hold
+ * to be the actual text address, not a descriptor.
  */
-_GLOBAL(__secondary_hold)
+       .globl  __secondary_hold
+__secondary_hold:
        mfmsr   r24
        ori     r24,r24,MSR_RI
        mtmsrd  r24                     /* RI on */
@@ -121,16 +128,16 @@ _GLOBAL(__secondary_hold)
        /* Tell the master cpu we're here */
        /* Relocation is off & we are located at an address less */
        /* than 0x100, so only need to grab low order offset.    */
-       std     r24,__secondary_hold_acknowledge@l(0)
+       std     r24,__secondary_hold_acknowledge-_stext(0)
        sync
 
        /* All secondary cpus wait here until told to start. */
-100:   ld      r4,__secondary_hold_spinloop@l(0)
-       cmpdi   0,r4,1
-       bne     100b
+100:   ld      r4,__secondary_hold_spinloop-_stext(0)
+       cmpdi   0,r4,0
+       beq     100b
 
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
-       LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init)
+       ld      r4,0(r4)                /* deref function descriptor */
        mtctr   r4
        mr      r3,r24
        bctr
@@ -147,6 +154,10 @@ exception_marker:
 /*
  * This is the start of the interrupt handlers for pSeries
  * This code runs with relocation off.
+ * Code from here to __end_interrupts gets copied down to real
+ * address 0x100 when we are running a relocatable kernel.
+ * Therefore any relative branches in this section must only
+ * branch to labels in this section.
  */
        . = 0x100
        .globl __start_interrupts
@@ -200,7 +211,20 @@ data_access_slb_pSeries:
        mfspr   r10,SPRN_SPRG1
        std     r10,PACA_EXSLB+EX_R13(r13)
        mfspr   r12,SPRN_SRR1           /* and SRR1 */
-       b       .slb_miss_realmode      /* Rel. branch works in real mode */
+#ifndef CONFIG_RELOCATABLE
+       b       .slb_miss_realmode
+#else
+       /*
+        * We can't just use a direct branch to .slb_miss_realmode
+        * because the distance from here to there depends on where
+        * the kernel ends up being put.
+        */
+       mfctr   r11
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10, .slb_miss_realmode)
+       mtctr   r10
+       bctr
+#endif
 
        STD_EXCEPTION_PSERIES(0x400, instruction_access)
 
@@ -225,7 +249,15 @@ instruction_access_slb_pSeries:
        mfspr   r10,SPRN_SPRG1
        std     r10,PACA_EXSLB+EX_R13(r13)
        mfspr   r12,SPRN_SRR1           /* and SRR1 */
-       b       .slb_miss_realmode      /* Rel. branch works in real mode */
+#ifndef CONFIG_RELOCATABLE
+       b       .slb_miss_realmode
+#else
+       mfctr   r11
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10, .slb_miss_realmode)
+       mtctr   r10
+       bctr
+#endif
 
        MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
        STD_EXCEPTION_PSERIES(0x600, alignment)
@@ -244,14 +276,12 @@ BEGIN_FTR_SECTION
        beq-    1f
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
        mr      r9,r13
-       mfmsr   r10
        mfspr   r13,SPRN_SPRG3
        mfspr   r11,SPRN_SRR0
-       clrrdi  r12,r13,32
-       oris    r12,r12,system_call_common@h
-       ori     r12,r12,system_call_common@l
+       ld      r12,PACAKBASE(r13)
+       ld      r10,PACAKMSR(r13)
+       LOAD_HANDLER(r12, system_call_entry)
        mtspr   SPRN_SRR0,r12
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
        mfspr   r12,SPRN_SRR1
        mtspr   SPRN_SRR1,r10
        rfid
@@ -325,16 +355,32 @@ do_stab_bolted_pSeries:
        mfspr   r12,SPRN_SPRG2
        EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
 
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Vectors for the FWNMI option.  Share common code.
+ */
+       .globl system_reset_fwnmi
+      .align 7
+system_reset_fwnmi:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+
+       .globl machine_check_fwnmi
+      .align 7
+machine_check_fwnmi:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+#endif /* CONFIG_PPC_PSERIES */
+
+#ifdef __DISABLED__
 /*
- * We have some room here  we use that to put
- * the peries slb miss user trampoline code so it's reasonably
- * away from slb_miss_user_common to avoid problems with rfid
- *
  * This is used for when the SLB miss handler has to go virtual,
  * which doesn't happen for now anymore but will once we re-implement
  * dynamic VSIDs for shared page tables
  */
-#ifdef __DISABLED__
 slb_miss_user_pseries:
        std     r10,PACA_EXGEN+EX_R10(r13)
        std     r11,PACA_EXGEN+EX_R11(r13)
@@ -357,25 +403,17 @@ slb_miss_user_pseries:
        b       .                               /* prevent spec. execution */
 #endif /* __DISABLED__ */
 
-#ifdef CONFIG_PPC_PSERIES
+       .align  7
+       .globl  __end_interrupts
+__end_interrupts:
+
 /*
- * Vectors for the FWNMI option.  Share common code.
+ * Code from here down to __end_handlers is invoked from the
+ * exception prologs above.  Because the prologs assemble the
+ * addresses of these handlers using the LOAD_HANDLER macro,
+ * which uses an addi instruction, these handlers must be in
+ * the first 32k of the kernel image.
  */
-       .globl system_reset_fwnmi
-      .align 7
-system_reset_fwnmi:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXGEN, system_reset_common)
-
-       .globl machine_check_fwnmi
-      .align 7
-machine_check_fwnmi:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common)
-
-#endif /* CONFIG_PPC_PSERIES */
 
 /*** Common interrupt handlers ***/
 
@@ -414,6 +452,10 @@ machine_check_common:
        STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
 #endif /* CONFIG_CBE_RAS */
 
+       .align  7
+system_call_entry:
+       b       system_call_common
+
 /*
  * Here we have detected that the kernel stack pointer is bad.
  * R9 contains the saved CR, r13 points to the paca,
@@ -456,65 +498,6 @@ bad_stack:
        bl      .kernel_bad_stack
        b       1b
 
-/*
- * Return from an exception with minimal checks.
- * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
- * If interrupts have been enabled, or anything has been
- * done that might have changed the scheduling status of
- * any task or sent any task a signal, you should use
- * ret_from_except or ret_from_except_lite instead of this.
- */
-fast_exc_return_irq:                   /* restores irq state too */
-       ld      r3,SOFTE(r1)
-       TRACE_AND_RESTORE_IRQ(r3);
-       ld      r12,_MSR(r1)
-       rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
-       stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
-       b       1f
-
-       .globl  fast_exception_return
-fast_exception_return:
-       ld      r12,_MSR(r1)
-1:     ld      r11,_NIP(r1)
-       andi.   r3,r12,MSR_RI           /* check if RI is set */
-       beq-    unrecov_fer
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       andi.   r3,r12,MSR_PR
-       beq     2f
-       ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
-#endif
-
-       ld      r3,_CCR(r1)
-       ld      r4,_LINK(r1)
-       ld      r5,_CTR(r1)
-       ld      r6,_XER(r1)
-       mtcr    r3
-       mtlr    r4
-       mtctr   r5
-       mtxer   r6
-       REST_GPR(0, r1)
-       REST_8GPRS(2, r1)
-
-       mfmsr   r10
-       rldicl  r10,r10,48,1            /* clear EE */
-       rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
-       mtmsrd  r10,1
-
-       mtspr   SPRN_SRR1,r12
-       mtspr   SPRN_SRR0,r11
-       REST_4GPRS(10, r1)
-       ld      r1,GPR1(r1)
-       rfid
-       b       .       /* prevent speculative execution */
-
-unrecov_fer:
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
 /*
  * Here r13 points to the paca, r9 contains the saved CR,
  * SRR0 and SRR1 are saved in r11 and r12,
@@ -616,6 +599,9 @@ unrecov_user_slb:
  */
 _GLOBAL(slb_miss_realmode)
        mflr    r10
+#ifdef CONFIG_RELOCATABLE
+       mtctr   r11
+#endif
 
        stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
        std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
@@ -666,11 +652,10 @@ BEGIN_FW_FTR_SECTION
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
        mfspr   r11,SPRN_SRR0
-       clrrdi  r10,r13,32
+       ld      r10,PACAKBASE(r13)
        LOAD_HANDLER(r10,unrecov_slb)
        mtspr   SPRN_SRR0,r10
-       mfmsr   r10
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
+       ld      r10,PACAKMSR(r13)
        mtspr   SPRN_SRR1,r10
        rfid
        b       .
@@ -766,6 +751,85 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        bl      .altivec_unavailable_exception
        b       .ret_from_except
 
+       .align  7
+       .globl vsx_unavailable_common
+vsx_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+       bne     .load_up_vsx
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+#endif
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .vsx_unavailable_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl  __end_handlers
+__end_handlers:
+
+/*
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
+ */
+fast_exc_return_irq:                   /* restores irq state too */
+       ld      r3,SOFTE(r1)
+       TRACE_AND_RESTORE_IRQ(r3);
+       ld      r12,_MSR(r1)
+       rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
+       stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
+       b       1f
+
+       .globl  fast_exception_return
+fast_exception_return:
+       ld      r12,_MSR(r1)
+1:     ld      r11,_NIP(r1)
+       andi.   r3,r12,MSR_RI           /* check if RI is set */
+       beq-    unrecov_fer
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       andi.   r3,r12,MSR_PR
+       beq     2f
+       ACCOUNT_CPU_USER_EXIT(r3, r4)
+2:
+#endif
+
+       ld      r3,_CCR(r1)
+       ld      r4,_LINK(r1)
+       ld      r5,_CTR(r1)
+       ld      r6,_XER(r1)
+       mtcr    r3
+       mtlr    r4
+       mtctr   r5
+       mtxer   r6
+       REST_GPR(0, r1)
+       REST_8GPRS(2, r1)
+
+       mfmsr   r10
+       rldicl  r10,r10,48,1            /* clear EE */
+       rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
+       mtmsrd  r10,1
+
+       mtspr   SPRN_SRR1,r12
+       mtspr   SPRN_SRR0,r11
+       REST_4GPRS(10, r1)
+       ld      r1,GPR1(r1)
+       rfid
+       b       .       /* prevent speculative execution */
+
+unrecov_fer:
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
 #ifdef CONFIG_ALTIVEC
 /*
  * load_up_altivec(unused, unused, tsk)
@@ -840,22 +904,6 @@ _STATIC(load_up_altivec)
        blr
 #endif /* CONFIG_ALTIVEC */
 
-       .align  7
-       .globl vsx_unavailable_common
-vsx_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
-       bne     .load_up_vsx
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .vsx_unavailable_exception
-       b       .ret_from_except
-
 #ifdef CONFIG_VSX
 /*
  * load_up_vsx(unused, unused, tsk)
@@ -1175,11 +1223,14 @@ _GLOBAL(generic_secondary_smp_init)
        /* turn on 64-bit mode */
        bl      .enable_64b_mode
 
+       /* get the TOC pointer (real address) */
+       bl      .relative_toc
+
        /* Set up a paca value for this processor. Since we have the
         * physical cpu id in r24, we need to search the pacas to find
         * which logical id maps to our physical one.
         */
-       LOAD_REG_IMMEDIATE(r13, paca)   /* Get base vaddr of paca array  */
+       LOAD_REG_ADDR(r13, paca)        /* Get base vaddr of paca array  */
        li      r5,0                    /* logical cpu id                */
 1:     lhz     r6,PACAHWCPUID(r13)     /* Load HW procid from paca      */
        cmpw    r6,r24                  /* Compare to our id             */
@@ -1208,7 +1259,7 @@ _GLOBAL(generic_secondary_smp_init)
        sync                            /* order paca.run and cur_cpu_spec */
 
        /* See if we need to call a cpu state restore handler */
-       LOAD_REG_IMMEDIATE(r23, cur_cpu_spec)
+       LOAD_REG_ADDR(r23, cur_cpu_spec)
        ld      r23,0(r23)
        ld      r23,CPU_SPEC_RESTORE(r23)
        cmpdi   0,r23,0
@@ -1224,10 +1275,15 @@ _GLOBAL(generic_secondary_smp_init)
        b       __secondary_start
 #endif
 
+/*
+ * Turn the MMU off.
+ * Assumes we're mapped EA == RA if the MMU is on.
+ */
 _STATIC(__mmu_off)
        mfmsr   r3
        andi.   r0,r3,MSR_IR|MSR_DR
        beqlr
+       mflr    r4
        andc    r3,r3,r0
        mtspr   SPRN_SRR0,r4
        mtspr   SPRN_SRR1,r3
@@ -1248,6 +1304,18 @@ _STATIC(__mmu_off)
  *
  */
 _GLOBAL(__start_initialization_multiplatform)
+       /* Make sure we are running in 64 bits mode */
+       bl      .enable_64b_mode
+
+       /* Get TOC pointer (current runtime address) */
+       bl      .relative_toc
+
+       /* find out where we are now */
+       bcl     20,31,$+4
+0:     mflr    r26                     /* r26 = runtime addr here */
+       addis   r26,r26,(_stext - 0b)@ha
+       addi    r26,r26,(_stext - 0b)@l /* current runtime base addr */
+
        /*
         * Are we booted from a PROM Of-type client-interface ?
         */
@@ -1259,9 +1327,6 @@ _GLOBAL(__start_initialization_multiplatform)
        mr      r31,r3
        mr      r30,r4
 
-       /* Make sure we are running in 64 bits mode */
-       bl      .enable_64b_mode
-
        /* Setup some critical 970 SPRs before switching MMU off */
        mfspr   r0,SPRN_PVR
        srwi    r0,r0,16
@@ -1276,9 +1341,7 @@ _GLOBAL(__start_initialization_multiplatform)
 1:     bl      .__cpu_preinit_ppc970
 2:
 
-       /* Switch off MMU if not already */
-       LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
-       add     r4,r4,r30
+       /* Switch off MMU if not already off */
        bl      .__mmu_off
        b       .__after_prom_start
 
@@ -1293,22 +1356,15 @@ _INIT_STATIC(__boot_from_prom)
        /*
         * Align the stack to 16-byte boundary
         * Depending on the size and layout of the ELF sections in the initial
-        * boot binary, the stack pointer will be unalignet on PowerMac
+        * boot binary, the stack pointer may be unaligned on PowerMac
         */
        rldicr  r1,r1,0,59
 
-       /* Make sure we are running in 64 bits mode */
-       bl      .enable_64b_mode
-
-       /* put a relocation offset into r3 */
-       bl      .reloc_offset
-
-       LOAD_REG_IMMEDIATE(r2,__toc_start)
-       addi    r2,r2,0x4000
-       addi    r2,r2,0x4000
-
-       /* Relocate the TOC from a virt addr to a real addr */
-       add     r2,r2,r3
+#ifdef CONFIG_RELOCATABLE
+       /* Relocate code for where we are now */
+       mr      r3,r26
+       bl      .relocate
+#endif
 
        /* Restore parameters */
        mr      r3,r31
@@ -1318,60 +1374,51 @@ _INIT_STATIC(__boot_from_prom)
        mr      r7,r27
 
        /* Do all of the interaction with OF client interface */
+       mr      r8,r26
        bl      .prom_init
        /* We never return */
        trap
 
 _STATIC(__after_prom_start)
+#ifdef CONFIG_RELOCATABLE
+       /* process relocations for the final address of the kernel */
+       lis     r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
+       sldi    r25,r25,32
+       mr      r3,r25
+       bl      .relocate
+#endif
 
 /*
- * We need to run with __start at physical address PHYSICAL_START.
+ * We need to run with _stext at physical address PHYSICAL_START.
  * This will leave some code in the first 256B of
  * real memory, which are reserved for software use.
- * The remainder of the first page is loaded with the fixed
- * interrupt vectors.  The next two pages are filled with
- * unknown exception placeholders.
  *
  * Note: This process overwrites the OF exception vectors.
- *     r26 == relocation offset
- *     r27 == KERNELBASE
  */
-       bl      .reloc_offset
-       mr      r26,r3
-       LOAD_REG_IMMEDIATE(r27, KERNELBASE)
-
-       LOAD_REG_IMMEDIATE(r3, PHYSICAL_START)  /* target addr */
-
-       // XXX FIXME: Use phys returned by OF (r30)
-       add     r4,r27,r26              /* source addr                   */
-                                       /* current address of _start     */
-                                       /*   i.e. where we are running   */
-                                       /*      the source addr          */
-
-       cmpdi   r4,0                    /* In some cases the loader may  */
-       bne     1f
-       b       .start_here_multiplatform /* have already put us at zero */
-                                       /* so we can skip the copy.      */
-1:     LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
-       sub     r5,r5,r27
-
+       li      r3,0                    /* target addr */
+       mr.     r4,r26                  /* In some cases the loader may  */
+       beq     9f                      /* have already put us at zero */
+       lis     r5,(copy_to_here - _stext)@ha
+       addi    r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
        li      r6,0x100                /* Start offset, the first 0x100 */
                                        /* bytes were copied earlier.    */
 
        bl      .copy_and_flush         /* copy the first n bytes        */
                                        /* this includes the code being  */
                                        /* executed here.                */
-
-       LOAD_REG_IMMEDIATE(r0, 4f)      /* Jump to the copy of this code */
-       mtctr   r0                      /* that we just made/relocated   */
+       addis   r8,r3,(4f - _stext)@ha  /* Jump to the copy of this code */
+       addi    r8,r8,(4f - _stext)@l   /* that we just made */
+       mtctr   r8
        bctr
 
-4:     LOAD_REG_IMMEDIATE(r5,klimit)
-       add     r5,r5,r26
-       ld      r5,0(r5)                /* get the value of klimit */
-       sub     r5,r5,r27
+4:     /* Now copy the rest of the kernel up to _end */
+       addis   r5,r26,(p_end - _stext)@ha
+       ld      r5,(p_end - _stext)@l(r5)       /* get _end */
        bl      .copy_and_flush         /* copy the rest */
-       b       .start_here_multiplatform
+
+9:     b       .start_here_multiplatform
+
+p_end: .llong  _end - _stext
 
 /*
  * Copy routine used to copy the kernel to start at physical address 0
@@ -1436,6 +1483,9 @@ _GLOBAL(pmac_secondary_start)
        /* turn on 64-bit mode */
        bl      .enable_64b_mode
 
+       /* get TOC pointer (real address) */
+       bl      .relative_toc
+
        /* Copy some CPU settings from CPU 0 */
        bl      .__restore_cpu_ppc970
 
@@ -1445,10 +1495,10 @@ _GLOBAL(pmac_secondary_start)
        mtmsrd  r3                      /* RI on */
 
        /* Set up a paca value for this processor. */
-       LOAD_REG_IMMEDIATE(r4, paca)    /* Get base vaddr of paca array */
-       mulli   r13,r24,PACA_SIZE        /* Calculate vaddr of right paca */
+       LOAD_REG_ADDR(r4,paca)          /* Get base vaddr of paca array */
+       mulli   r13,r24,PACA_SIZE       /* Calculate vaddr of right paca */
        add     r13,r13,r4              /* for this processor.          */
-       mtspr   SPRN_SPRG3,r13           /* Save vaddr of paca in SPRG3 */
+       mtspr   SPRN_SPRG3,r13          /* Save vaddr of paca in SPRG3  */
 
        /* Create a temp kernel stack for use before relocation is on.  */
        ld      r1,PACAEMERGSP(r13)
@@ -1476,9 +1526,6 @@ __secondary_start:
        /* Set thread priority to MEDIUM */
        HMT_MEDIUM
 
-       /* Load TOC */
-       ld      r2,PACATOC(r13)
-
        /* Do early setup for that CPU (stab, slb, hash table pointer) */
        bl      .early_setup_secondary
 
@@ -1515,9 +1562,11 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 /* 
  * Running with relocation on at this point.  All we want to do is
- * zero the stack back-chain pointer before going into C code.
+ * zero the stack back-chain pointer and get the TOC virtual address
+ * before going into C code.
  */
 _GLOBAL(start_secondary_prolog)
+       ld      r2,PACATOC(r13)
        li      r3,0
        std     r3,0(r1)                /* Zero the stack frame pointer */
        bl      .start_secondary
@@ -1529,34 +1578,46 @@ _GLOBAL(start_secondary_prolog)
  */
 _GLOBAL(enable_64b_mode)
        mfmsr   r11                     /* grab the current MSR */
-       li      r12,1
-       rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
-       or      r11,r11,r12
-       li      r12,1
-       rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+       li      r12,(MSR_SF | MSR_ISF)@highest
+       sldi    r12,r12,48
        or      r11,r11,r12
        mtmsrd  r11
        isync
        blr
 
+/*
+ * This puts the TOC pointer into r2, offset by 0x8000 (as expected
+ * by the toolchain).  It computes the correct value for wherever we
+ * are running at the moment, using position-independent code.
+ */
+_GLOBAL(relative_toc)
+       mflr    r0
+       bcl     20,31,$+4
+0:     mflr    r9
+       ld      r2,(p_toc - 0b)(r9)
+       add     r2,r2,r9
+       mtlr    r0
+       blr
+
+p_toc: .llong  __toc_start + 0x8000 - 0b
+
 /*
  * This is where the main kernel code starts.
  */
 _INIT_STATIC(start_here_multiplatform)
-       /* get a new offset, now that the kernel has moved. */
-       bl      .reloc_offset
-       mr      r26,r3
+       /* set up the TOC (real address) */
+       bl      .relative_toc
 
        /* Clear out the BSS. It may have been done in prom_init,
         * already but that's irrelevant since prom_init will soon
         * be detached from the kernel completely. Besides, we need
         * to clear it now for kexec-style entry.
         */
-       LOAD_REG_IMMEDIATE(r11,__bss_stop)
-       LOAD_REG_IMMEDIATE(r8,__bss_start)
+       LOAD_REG_ADDR(r11,__bss_stop)
+       LOAD_REG_ADDR(r8,__bss_start)
        sub     r11,r11,r8              /* bss size                     */
        addi    r11,r11,7               /* round up to an even double word */
-       rldicl. r11,r11,61,3            /* shift right by 3             */
+       srdi.   r11,r11,3               /* shift right by 3             */
        beq     4f
        addi    r8,r8,-8
        li      r0,0
@@ -1569,35 +1630,35 @@ _INIT_STATIC(start_here_multiplatform)
        ori     r6,r6,MSR_RI
        mtmsrd  r6                      /* RI on */
 
-       /* The following gets the stack and TOC set up with the regs */
+#ifdef CONFIG_RELOCATABLE
+       /* Save the physical address we're running at in kernstart_addr */
+       LOAD_REG_ADDR(r4, kernstart_addr)
+       clrldi  r0,r25,2
+       std     r0,0(r4)
+#endif
+
+       /* The following gets the stack set up with the regs */
        /* pointing to the real addr of the kernel stack.  This is   */
        /* all done to support the C function call below which sets  */
        /* up the htab.  This is done because we have relocated the  */
        /* kernel but are still running in real mode. */
 
-       LOAD_REG_IMMEDIATE(r3,init_thread_union)
-       add     r3,r3,r26
+       LOAD_REG_ADDR(r3,init_thread_union)
 
-       /* set up a stack pointer (physical address) */
+       /* set up a stack pointer */
        addi    r1,r3,THREAD_SIZE
        li      r0,0
        stdu    r0,-STACK_FRAME_OVERHEAD(r1)
 
-       /* set up the TOC (physical address) */
-       LOAD_REG_IMMEDIATE(r2,__toc_start)
-       addi    r2,r2,0x4000
-       addi    r2,r2,0x4000
-       add     r2,r2,r26
-
        /* Do very early kernel initializations, including initial hash table,
         * stab and slb setup before we turn on relocation.     */
 
        /* Restore parameters passed from prom_init/kexec */
        mr      r3,r31
-       bl      .early_setup
+       bl      .early_setup            /* also sets r13 and SPRG3 */
 
-       LOAD_REG_IMMEDIATE(r3, .start_here_common)
-       LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
+       LOAD_REG_ADDR(r3, .start_here_common)
+       ld      r4,PACAKMSR(r13)
        mtspr   SPRN_SRR0,r3
        mtspr   SPRN_SRR1,r4
        rfid
@@ -1606,20 +1667,10 @@ _INIT_STATIC(start_here_multiplatform)
        /* This is where all platforms converge execution */
 _INIT_GLOBAL(start_here_common)
        /* relocation is on at this point */
+       std     r1,PACAKSAVE(r13)
 
-       /* The following code sets up the SP and TOC now that we are */
-       /* running with translation enabled. */
-
-       LOAD_REG_IMMEDIATE(r3,init_thread_union)
-
-       /* set up the stack */
-       addi    r1,r3,THREAD_SIZE
-       li      r0,0
-       stdu    r0,-STACK_FRAME_OVERHEAD(r1)
-
-       /* Load the TOC */
+       /* Load the TOC (virtual address) */
        ld      r2,PACATOC(r13)
-       std     r1,PACAKSAVE(r13)
 
        bl      .setup_system
 
index 3cb52fa0eda319a7ff52c496e89802b162a5c56f..590304c24dad37ea5d49f06c6176eb9ae1aab2ac 100644 (file)
@@ -422,7 +422,6 @@ skpinv:     addi    r6,r6,1                         /* Increment */
  *   r12 is pointer to the pte
  */
 #ifdef CONFIG_PTE_64BIT
-#define PTE_FLAGS_OFFSET       4
 #define FIND_PTE       \
        rlwinm  r12, r10, 13, 19, 29;   /* Compute pgdir/pmd offset */  \
        lwzx    r11, r12, r11;          /* Get pgd/pmd entry */         \
@@ -431,7 +430,6 @@ skpinv:     addi    r6,r6,1                         /* Increment */
        rlwimi  r12, r10, 23, 20, 28;   /* Compute pte address */       \
        lwz     r11, 4(r12);            /* Get pte entry */
 #else
-#define PTE_FLAGS_OFFSET       0
 #define FIND_PTE       \
        rlwimi  r11, r10, 12, 20, 29;   /* Create L1 (pgdir/pmd) address */     \
        lwz     r11, 0(r11);            /* Get L1 entry */                      \
@@ -579,13 +577,19 @@ interrupt_base:
 
        FIND_PTE
        andc.   r13,r13,r11             /* Check permission */
-       bne     2f                      /* Bail if permission mismach */
 
 #ifdef CONFIG_PTE_64BIT
-       lwz     r13, 0(r12)
+#ifdef CONFIG_SMP
+       subf    r10,r11,r12             /* create false data dep */
+       lwzx    r13,r11,r10             /* Get upper pte bits */
+#else
+       lwz     r13,0(r12)              /* Get upper pte bits */
+#endif
 #endif
 
-        /* Jump to common tlb load */
+       bne     2f                      /* Bail if permission/valid mismach */
+
+       /* Jump to common tlb load */
        b       finish_tlb_load
 2:
        /* The bailout.  Restore registers to pre-exception conditions
@@ -640,12 +644,18 @@ interrupt_base:
 
        FIND_PTE
        andc.   r13,r13,r11             /* Check permission */
-       bne     2f                      /* Bail if permission mismach */
 
 #ifdef CONFIG_PTE_64BIT
-       lwz     r13, 0(r12)
+#ifdef CONFIG_SMP
+       subf    r10,r11,r12             /* create false data dep */
+       lwzx    r13,r11,r10             /* Get upper pte bits */
+#else
+       lwz     r13,0(r12)              /* Get upper pte bits */
+#endif
 #endif
 
+       bne     2f                      /* Bail if permission mismach */
+
        /* Jump to common TLB load point */
        b       finish_tlb_load
 
@@ -702,7 +712,7 @@ interrupt_base:
 /*
  * Both the instruction and data TLB miss get to this
  * point to load the TLB.
- *     r10 - EA of fault
+ *     r10 - available to use
  *     r11 - TLB (info from Linux PTE)
  *     r12 - available to use
  *     r13 - upper bits of PTE (if PTE_64BIT) or available to use
index 550a19399bfaac81bceabfbeb60f4a29e0e0752f..ea1ba89f9c9001ccff8b2d5256d09fe17dafd4c7 100644 (file)
@@ -51,17 +51,6 @@ static int protect4gb = 1;
 
 static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
 
-static inline unsigned long iommu_num_pages(unsigned long vaddr,
-                                           unsigned long slen)
-{
-       unsigned long npages;
-
-       npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK);
-       npages >>= IOMMU_PAGE_SHIFT;
-
-       return npages;
-}
-
 static int __init setup_protect4gb(char *str)
 {
        if (strcmp(str, "on") == 0)
@@ -325,7 +314,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                }
                /* Allocate iommu entries for that segment */
                vaddr = (unsigned long) sg_virt(s);
-               npages = iommu_num_pages(vaddr, slen);
+               npages = iommu_num_pages(vaddr, slen, IOMMU_PAGE_SIZE);
                align = 0;
                if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
                    (vaddr & ~PAGE_MASK) == 0)
@@ -418,7 +407,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                        unsigned long vaddr, npages;
 
                        vaddr = s->dma_address & IOMMU_PAGE_MASK;
-                       npages = iommu_num_pages(s->dma_address, s->dma_length);
+                       npages = iommu_num_pages(s->dma_address, s->dma_length,
+                                                IOMMU_PAGE_SIZE);
                        __iommu_free(tbl, vaddr, npages);
                        s->dma_address = DMA_ERROR_CODE;
                        s->dma_length = 0;
@@ -452,7 +442,8 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
 
                if (sg->dma_length == 0)
                        break;
-               npages = iommu_num_pages(dma_handle, sg->dma_length);
+               npages = iommu_num_pages(dma_handle, sg->dma_length,
+                                        IOMMU_PAGE_SIZE);
                __iommu_free(tbl, dma_handle, npages);
                sg = sg_next(sg);
        }
@@ -584,7 +575,7 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
        BUG_ON(direction == DMA_NONE);
 
        uaddr = (unsigned long)vaddr;
-       npages = iommu_num_pages(uaddr, size);
+       npages = iommu_num_pages(uaddr, size, IOMMU_PAGE_SIZE);
 
        if (tbl) {
                align = 0;
@@ -617,7 +608,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
        BUG_ON(direction == DMA_NONE);
 
        if (tbl) {
-               npages = iommu_num_pages(dma_handle, size);
+               npages = iommu_num_pages(dma_handle, size, IOMMU_PAGE_SIZE);
                iommu_free(tbl, dma_handle, npages);
        }
 }
index d972decf0324d4b92e748f4a271e4ad3b4ed4475..ac222d0ab12e86406bcbc6247adb3b8150ed49ee 100644 (file)
@@ -439,8 +439,8 @@ void do_softirq(void)
 
 static LIST_HEAD(irq_hosts);
 static DEFINE_SPINLOCK(irq_big_lock);
-static DEFINE_PER_CPU(unsigned int, irq_radix_reader);
-static unsigned int irq_radix_writer;
+static unsigned int revmap_trees_allocated;
+static DEFINE_MUTEX(revmap_trees_mutex);
 struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_host *irq_default_host;
@@ -583,57 +583,6 @@ void irq_set_virq_count(unsigned int count)
                irq_virq_count = count;
 }
 
-/* radix tree not lockless safe ! we use a brlock-type mecanism
- * for now, until we can use a lockless radix tree
- */
-static void irq_radix_wrlock(unsigned long *flags)
-{
-       unsigned int cpu, ok;
-
-       spin_lock_irqsave(&irq_big_lock, *flags);
-       irq_radix_writer = 1;
-       smp_mb();
-       do {
-               barrier();
-               ok = 1;
-               for_each_possible_cpu(cpu) {
-                       if (per_cpu(irq_radix_reader, cpu)) {
-                               ok = 0;
-                               break;
-                       }
-               }
-               if (!ok)
-                       cpu_relax();
-       } while(!ok);
-}
-
-static void irq_radix_wrunlock(unsigned long flags)
-{
-       smp_wmb();
-       irq_radix_writer = 0;
-       spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
-static void irq_radix_rdlock(unsigned long *flags)
-{
-       local_irq_save(*flags);
-       __get_cpu_var(irq_radix_reader) = 1;
-       smp_mb();
-       if (likely(irq_radix_writer == 0))
-               return;
-       __get_cpu_var(irq_radix_reader) = 0;
-       smp_wmb();
-       spin_lock(&irq_big_lock);
-       __get_cpu_var(irq_radix_reader) = 1;
-       spin_unlock(&irq_big_lock);
-}
-
-static void irq_radix_rdunlock(unsigned long flags)
-{
-       __get_cpu_var(irq_radix_reader) = 0;
-       local_irq_restore(flags);
-}
-
 static int irq_setup_virq(struct irq_host *host, unsigned int virq,
                            irq_hw_number_t hwirq)
 {
@@ -788,7 +737,6 @@ void irq_dispose_mapping(unsigned int virq)
 {
        struct irq_host *host;
        irq_hw_number_t hwirq;
-       unsigned long flags;
 
        if (virq == NO_IRQ)
                return;
@@ -821,12 +769,16 @@ void irq_dispose_mapping(unsigned int virq)
                        host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
                break;
        case IRQ_HOST_MAP_TREE:
-               /* Check if radix tree allocated yet */
-               if (host->revmap_data.tree.gfp_mask == 0)
+               /*
+                * Check if radix tree allocated yet, if not then nothing to
+                * remove.
+                */
+               smp_rmb();
+               if (revmap_trees_allocated < 1)
                        break;
-               irq_radix_wrlock(&flags);
+               mutex_lock(&revmap_trees_mutex);
                radix_tree_delete(&host->revmap_data.tree, hwirq);
-               irq_radix_wrunlock(flags);
+               mutex_unlock(&revmap_trees_mutex);
                break;
        }
 
@@ -875,43 +827,62 @@ unsigned int irq_find_mapping(struct irq_host *host,
 EXPORT_SYMBOL_GPL(irq_find_mapping);
 
 
-unsigned int irq_radix_revmap(struct irq_host *host,
-                             irq_hw_number_t hwirq)
+unsigned int irq_radix_revmap_lookup(struct irq_host *host,
+                                    irq_hw_number_t hwirq)
 {
-       struct radix_tree_root *tree;
        struct irq_map_entry *ptr;
        unsigned int virq;
-       unsigned long flags;
 
        WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
 
-       /* Check if the radix tree exist yet. We test the value of
-        * the gfp_mask for that. Sneaky but saves another int in the
-        * structure. If not, we fallback to slow mode
+       /*
+        * Check if the radix tree exists and has bee initialized.
+        * If not, we fallback to slow mode
         */
-       tree = &host->revmap_data.tree;
-       if (tree->gfp_mask == 0)
+       if (revmap_trees_allocated < 2)
                return irq_find_mapping(host, hwirq);
 
        /* Now try to resolve */
-       irq_radix_rdlock(&flags);
-       ptr = radix_tree_lookup(tree, hwirq);
-       irq_radix_rdunlock(flags);
+       /*
+        * No rcu_read_lock(ing) needed, the ptr returned can't go under us
+        * as it's referencing an entry in the static irq_map table.
+        */
+       ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
 
-       /* Found it, return */
-       if (ptr) {
+       /*
+        * If found in radix tree, then fine.
+        * Else fallback to linear lookup - this should not happen in practice
+        * as it means that we failed to insert the node in the radix tree.
+        */
+       if (ptr)
                virq = ptr - irq_map;
-               return virq;
-       }
+       else
+               virq = irq_find_mapping(host, hwirq);
+
+       return virq;
+}
+
+void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
+                            irq_hw_number_t hwirq)
+{
+
+       WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
+
+       /*
+        * Check if the radix tree exists yet.
+        * If not, then the irq will be inserted into the tree when it gets
+        * initialized.
+        */
+       smp_rmb();
+       if (revmap_trees_allocated < 1)
+               return;
 
-       /* If not there, try to insert it */
-       virq = irq_find_mapping(host, hwirq);
        if (virq != NO_IRQ) {
-               irq_radix_wrlock(&flags);
-               radix_tree_insert(tree, hwirq, &irq_map[virq]);
-               irq_radix_wrunlock(flags);
+               mutex_lock(&revmap_trees_mutex);
+               radix_tree_insert(&host->revmap_data.tree, hwirq,
+                                 &irq_map[virq]);
+               mutex_unlock(&revmap_trees_mutex);
        }
-       return virq;
 }
 
 unsigned int irq_linear_revmap(struct irq_host *host,
@@ -1020,14 +991,44 @@ void irq_early_init(void)
 static int irq_late_init(void)
 {
        struct irq_host *h;
-       unsigned long flags;
+       unsigned int i;
 
-       irq_radix_wrlock(&flags);
+       /*
+        * No mutual exclusion with respect to accessors of the tree is needed
+        * here as the synchronization is done via the state variable
+        * revmap_trees_allocated.
+        */
        list_for_each_entry(h, &irq_hosts, link) {
                if (h->revmap_type == IRQ_HOST_MAP_TREE)
-                       INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC);
+                       INIT_RADIX_TREE(&h->revmap_data.tree, GFP_KERNEL);
+       }
+
+       /*
+        * Make sure the radix trees inits are visible before setting
+        * the flag
+        */
+       smp_wmb();
+       revmap_trees_allocated = 1;
+
+       /*
+        * Insert the reverse mapping for those interrupts already present
+        * in irq_map[].
+        */
+       mutex_lock(&revmap_trees_mutex);
+       for (i = 0; i < irq_virq_count; i++) {
+               if (irq_map[i].host &&
+                   (irq_map[i].host->revmap_type == IRQ_HOST_MAP_TREE))
+                       radix_tree_insert(&irq_map[i].host->revmap_data.tree,
+                                         irq_map[i].hwirq, &irq_map[i]);
        }
-       irq_radix_wrunlock(flags);
+       mutex_unlock(&revmap_trees_mutex);
+
+       /*
+        * Make sure the radix trees insertions are visible before setting
+        * the flag
+        */
+       smp_wmb();
+       revmap_trees_allocated = 2;
 
        return 0;
 }
index b3eef30b5131a0d1eaf43551ae0d0aa2ccda6d92..d051e8cbcd0373138f4c88cd59538067e73bbec1 100644 (file)
@@ -510,10 +510,10 @@ static ssize_t update_ppp(u64 *entitlement, u8 *weight)
                return -EINVAL;
 
        pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
-                __FUNCTION__, ppp_data.entitlement, ppp_data.weight);
+                __func__, ppp_data.entitlement, ppp_data.weight);
 
        pr_debug("%s: new_entitled = %lu, new_weight = %u\n",
-                __FUNCTION__, new_entitled, new_weight);
+                __func__, new_entitled, new_weight);
 
        retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight);
        return retval;
@@ -556,10 +556,10 @@ static ssize_t update_mpp(u64 *entitlement, u8 *weight)
                return -EINVAL;
 
        pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
-                __FUNCTION__, mpp_data.entitled_mem, mpp_data.mem_weight);
+                __func__, mpp_data.entitled_mem, mpp_data.mem_weight);
 
        pr_debug("%s: new_entitled = %lu, new_weight = %u\n",
-                __FUNCTION__, new_entitled, new_weight);
+                __func__, new_entitled, new_weight);
 
        rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight);
        return rc;
index 85cb6f340846248882074a2b08f0e920f6acbb2f..2d29752cbe169ea9398fbd1381cd9eff64ec28c8 100644 (file)
@@ -31,11 +31,14 @@ _GLOBAL(reloc_offset)
        mflr    r0
        bl      1f
 1:     mflr    r3
-       LOAD_REG_IMMEDIATE(r4,1b)
+       PPC_LL  r4,(2f-1b)(r3)
        subf    r3,r4,r3
        mtlr    r0
        blr
 
+       .align  3
+2:     PPC_LONG 1b
+
 /*
  * add_reloc_offset(x) returns x + reloc_offset().
  */
@@ -43,12 +46,15 @@ _GLOBAL(add_reloc_offset)
        mflr    r0
        bl      1f
 1:     mflr    r5
-       LOAD_REG_IMMEDIATE(r4,1b)
+       PPC_LL  r4,(2f-1b)(r5)
        subf    r5,r4,r5
        add     r3,r3,r5
        mtlr    r0
        blr
 
+       .align  3
+2:     PPC_LONG 1b
+
 _GLOBAL(kernel_execve)
        li      r0,__NR_execve
        sc
index 7a6dfbca76821bd5e49cbbb04fcda1d045441907..6a9b4bf0d173e0f0a656c0ef313af7fed325df59 100644 (file)
@@ -274,6 +274,10 @@ _GLOBAL(real_writeb)
 /*
  * Flush MMU TLB
  */
+#ifndef CONFIG_FSL_BOOKE
+_GLOBAL(_tlbil_all)
+_GLOBAL(_tlbil_pid)
+#endif
 _GLOBAL(_tlbia)
 #if defined(CONFIG_40x)
        sync                    /* Flush to memory before changing mapping */
@@ -344,6 +348,9 @@ _GLOBAL(_tlbia)
 /*
  * Flush MMU TLB for a particular address
  */
+#ifndef CONFIG_FSL_BOOKE
+_GLOBAL(_tlbil_va)
+#endif
 _GLOBAL(_tlbie)
 #if defined(CONFIG_40x)
        /* We run the search with interrupts disabled because we have to change
@@ -436,6 +443,53 @@ _GLOBAL(_tlbie)
 #endif /* ! CONFIG_40x */
        blr
 
+#if defined(CONFIG_FSL_BOOKE)
+/*
+ * Flush MMU TLB, but only on the local processor (no broadcast)
+ */
+_GLOBAL(_tlbil_all)
+#define MMUCSR0_TLBFI  (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
+                        MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
+       li      r3,(MMUCSR0_TLBFI)@l
+       mtspr   SPRN_MMUCSR0, r3
+1:
+       mfspr   r3,SPRN_MMUCSR0
+       andi.   r3,r3,MMUCSR0_TLBFI@l
+       bne     1b
+       blr
+
+/*
+ * Flush MMU TLB for a particular process id, but only on the local processor
+ * (no broadcast)
+ */
+_GLOBAL(_tlbil_pid)
+/* we currently do an invalidate all since we don't have per pid invalidate */
+       li      r3,(MMUCSR0_TLBFI)@l
+       mtspr   SPRN_MMUCSR0, r3
+1:
+       mfspr   r3,SPRN_MMUCSR0
+       andi.   r3,r3,MMUCSR0_TLBFI@l
+       bne     1b
+       blr
+
+/*
+ * Flush MMU TLB for a particular address, but only on the local processor
+ * (no broadcast)
+ */
+_GLOBAL(_tlbil_va)
+       slwi    r4,r4,16
+       mtspr   SPRN_MAS6,r4            /* assume AS=0 for now */
+       tlbsx   0,r3
+       mfspr   r4,SPRN_MAS1            /* check valid */
+       andis.  r3,r4,MAS1_VALID@h
+       beqlr
+       rlwinm  r4,r4,0,1,31
+       mtspr   SPRN_MAS1,r4
+       tlbwe
+       blr
+#endif /* CONFIG_FSL_BOOKE */
+
+
 /*
  * Flush instruction cache.
  * This is a no-op on the 601.
@@ -846,8 +900,10 @@ _GLOBAL(kernel_thread)
        li      r4,0            /* new sp (unused) */
        li      r0,__NR_clone
        sc
-       cmpwi   0,r3,0          /* parent or child? */
-       bne     1f              /* return if parent */
+       bns+    1f              /* did system call indicate error? */
+       neg     r3,r3           /* if so, make return code negative */
+1:     cmpwi   0,r3,0          /* parent or child? */
+       bne     2f              /* return if parent */
        li      r0,0            /* make top-level stack frame */
        stwu    r0,-16(r1)
        mtlr    r30             /* fn addr in lr */
@@ -857,7 +913,7 @@ _GLOBAL(kernel_thread)
        li      r0,__NR_exit    /* exit if function returns */
        li      r3,0
        sc
-1:     lwz     r30,8(r1)
+2:     lwz     r30,8(r1)
        lwz     r31,12(r1)
        addi    r1,r1,16
        blr
index 4dd70cf7bb4eb6e17e8755b4f5fad3b4fb9ae49d..3053fe5c62f2a67694d430187df900495c19531b 100644 (file)
@@ -426,8 +426,10 @@ _GLOBAL(kernel_thread)
        li      r4,0            /* new sp (unused) */
        li      r0,__NR_clone
        sc
-       cmpdi   0,r3,0          /* parent or child? */
-       bne     1f              /* return if parent */
+       bns+    1f              /* did system call indicate error? */
+       neg     r3,r3           /* if so, make return code negative */
+1:     cmpdi   0,r3,0          /* parent or child? */
+       bne     2f              /* return if parent */
        li      r0,0
        stdu    r0,-STACK_FRAME_OVERHEAD(r1)
        ld      r2,8(r29)
@@ -438,7 +440,7 @@ _GLOBAL(kernel_thread)
        li      r0,__NR_exit    /* exit after child exits */
         li     r3,0
        sc
-1:     addi    r1,r1,STACK_FRAME_OVERHEAD      
+2:     addi    r1,r1,STACK_FRAME_OVERHEAD
        ld      r29,-24(r1)
        ld      r30,-16(r1)
        blr
index e9be908f199b6fa46ee4ec2226316db2ad1702c6..93ae5b169f418b59e9fd7dadc1f5b89890a9d6fc 100644 (file)
@@ -78,7 +78,7 @@ struct of_device *of_device_alloc(struct device_node *np,
        dev->dev.parent = parent;
        dev->dev.release = of_release_dev;
        dev->dev.archdata.of_node = np;
-       dev->dev.archdata.numa_node = of_node_to_nid(np);
+       set_dev_node(&dev->dev, of_node_to_nid(np));
 
        if (bus_id)
                strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
index c9bf17eec31b1d14c5fd144b18e372e05e6b5868..48a347133f41607c84a05e4b26647f17e4b6829c 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <asm/lppaca.h>
 #include <asm/paca.h>
+#include <asm/sections.h>
 
 /* This symbol is provided by the linker - let it fill in the paca
  * field correctly */
@@ -79,6 +80,8 @@ void __init initialise_pacas(void)
                new_paca->lock_token = 0x8000;
                new_paca->paca_index = cpu;
                new_paca->kernel_toc = kernel_toc;
+               new_paca->kernelbase = (unsigned long) _stext;
+               new_paca->kernel_msr = MSR_KERNEL;
                new_paca->hw_cpu_id = 0xffff;
                new_paca->slb_shadow_ptr = &slb_shadow[cpu];
                new_paca->__current = &init_task;
index ea0c61e09b7640553cf70c92b184339ff3bfd0bc..01ce8c38bae635334b6b3b9d104f0bb26d5861fe 100644 (file)
@@ -56,6 +56,34 @@ resource_size_t isa_mem_base;
 /* Default PCI flags is 0 */
 unsigned int ppc_pci_flags;
 
+static struct dma_mapping_ops *pci_dma_ops;
+
+void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
+{
+       pci_dma_ops = dma_ops;
+}
+
+struct dma_mapping_ops *get_pci_dma_ops(void)
+{
+       return pci_dma_ops;
+}
+EXPORT_SYMBOL(get_pci_dma_ops);
+
+int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+       return dma_set_mask(&dev->dev, mask);
+}
+
+int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+       int rc;
+
+       rc = dma_set_mask(&dev->dev, mask);
+       dev->dev.coherent_dma_mask = dev->dma_mask;
+
+       return rc;
+}
+
 struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
 {
        struct pci_controller *phb;
@@ -180,6 +208,26 @@ char __devinit *pcibios_setup(char *str)
        return str;
 }
 
+void __devinit pcibios_setup_new_device(struct pci_dev *dev)
+{
+       struct dev_archdata *sd = &dev->dev.archdata;
+
+       sd->of_node = pci_device_to_OF_node(dev);
+
+       DBG("PCI: device %s OF node: %s\n", pci_name(dev),
+           sd->of_node ? sd->of_node->full_name : "<none>");
+
+       sd->dma_ops = pci_dma_ops;
+#ifdef CONFIG_PPC32
+       sd->dma_data = (void *)PCI_DRAM_OFFSET;
+#endif
+       set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+       if (ppc_md.pci_dma_dev_setup)
+               ppc_md.pci_dma_dev_setup(dev);
+}
+EXPORT_SYMBOL(pcibios_setup_new_device);
+
 /*
  * Reads the interrupt pin to determine if interrupt is use by card.
  * If the interrupt is used, then gets the interrupt line from the
@@ -371,7 +419,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
        struct pci_dev *pdev = NULL;
        struct resource *found = NULL;
        unsigned long prot = pgprot_val(protection);
-       unsigned long offset = pfn << PAGE_SHIFT;
+       resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT;
        int i;
 
        if (page_is_ram(pfn))
@@ -422,7 +470,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
 int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                        enum pci_mmap_state mmap_state, int write_combine)
 {
-       resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
+       resource_size_t offset =
+               ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
        struct resource *rp;
        int ret;
 
@@ -731,11 +780,6 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 
        res->start = (res->start + offset) & mask;
        res->end = (res->end + offset) & mask;
-
-       pr_debug("PCI:%s            %016llx-%016llx\n",
-                pci_name(dev),
-                (unsigned long long)res->start,
-                (unsigned long long)res->end);
 }
 
 
@@ -781,6 +825,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
                         (unsigned int)res->flags);
 
                fixup_resource(res, dev);
+
+               pr_debug("PCI:%s            %016llx-%016llx\n",
+                        pci_name(dev),
+                        (unsigned long long)res->start,
+                        (unsigned long long)res->end);
        }
 
        /* Call machine specific resource fixup */
@@ -789,58 +838,127 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
 
-static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
+/* This function tries to figure out if a bridge resource has been initialized
+ * by the firmware or not. It doesn't have to be absolutely bullet proof, but
+ * things go more smoothly when it gets it right. It should covers cases such
+ * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges
+ */
+static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
+                                                          struct resource *res)
 {
        struct pci_controller *hose = pci_bus_to_host(bus);
        struct pci_dev *dev = bus->self;
+       resource_size_t offset;
+       u16 command;
+       int i;
 
-       pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
+       /* We don't do anything if PCI_PROBE_ONLY is set */
+       if (ppc_pci_flags & PPC_PCI_PROBE_ONLY)
+               return 0;
 
-       /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
-        * now differently between 32 and 64 bits.
-        */
-       if (dev != NULL) {
-               struct resource *res;
-               int i;
+       /* Job is a bit different between memory and IO */
+       if (res->flags & IORESOURCE_MEM) {
+               /* If the BAR is non-0 (res != pci_mem_offset) then it's probably been
+                * initialized by somebody
+                */
+               if (res->start != hose->pci_mem_offset)
+                       return 0;
 
-               for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
-                       if ((res = bus->resource[i]) == NULL)
-                               continue;
-                       if (!res->flags)
-                               continue;
-                       if (i >= 3 && bus->self->transparent)
-                               continue;
-                       /* On PowerMac, Apple leaves bridge windows open over
-                        * an inaccessible region of memory space (0...fffff)
-                        * which is somewhat bogus, but that's what they think
-                        * means disabled...
-                        *
-                        * We clear those to force them to be reallocated later
-                        *
-                        * We detect such regions by the fact that the base is
-                        * equal to the pci_mem_offset of the host bridge and
-                        * their size is smaller than 1M.
-                        */
-                       if (res->flags & IORESOURCE_MEM &&
-                           res->start == hose->pci_mem_offset &&
-                           res->end < 0x100000) {
-                               printk(KERN_INFO
-                                      "PCI: Closing bogus Apple Firmware"
-                                      " region %d on bus 0x%02x\n",
-                                      i, bus->number);
-                               res->flags = 0;
-                               continue;
-                       }
+               /* The BAR is 0, let's check if memory decoding is enabled on
+                * the bridge. If not, we consider it unassigned
+                */
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               if ((command & PCI_COMMAND_MEMORY) == 0)
+                       return 1;
 
-                       pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
-                                pci_name(dev), i,
-                                (unsigned long long)res->start,\
-                                (unsigned long long)res->end,
-                                (unsigned int)res->flags);
+               /* Memory decoding is enabled and the BAR is 0. If any of the bridge
+                * resources covers that starting address (0 then it's good enough for
+                * us for memory
+                */
+               for (i = 0; i < 3; i++) {
+                       if ((hose->mem_resources[i].flags & IORESOURCE_MEM) &&
+                           hose->mem_resources[i].start == hose->pci_mem_offset)
+                               return 0;
+               }
 
-                       fixup_resource(res, dev);
+               /* Well, it starts at 0 and we know it will collide so we may as
+                * well consider it as unassigned. That covers the Apple case.
+                */
+               return 1;
+       } else {
+               /* If the BAR is non-0, then we consider it assigned */
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               if (((res->start - offset) & 0xfffffffful) != 0)
+                       return 0;
+
+               /* Here, we are a bit different than memory as typically IO space
+                * starting at low addresses -is- valid. What we do instead if that
+                * we consider as unassigned anything that doesn't have IO enabled
+                * in the PCI command register, and that's it.
+                */
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               if (command & PCI_COMMAND_IO)
+                       return 0;
+
+               /* It's starting at 0 and IO is disabled in the bridge, consider
+                * it unassigned
+                */
+               return 1;
+       }
+}
+
+/* Fixup resources of a PCI<->PCI bridge */
+static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
+{
+       struct resource *res;
+       int i;
+
+       struct pci_dev *dev = bus->self;
+
+       for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+               if ((res = bus->resource[i]) == NULL)
+                       continue;
+               if (!res->flags)
+                       continue;
+               if (i >= 3 && bus->self->transparent)
+                       continue;
+
+               pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
+                        pci_name(dev), i,
+                        (unsigned long long)res->start,\
+                        (unsigned long long)res->end,
+                        (unsigned int)res->flags);
+
+               /* Perform fixup */
+               fixup_resource(res, dev);
+
+               /* Try to detect uninitialized P2P bridge resources,
+                * and clear them out so they get re-assigned later
+                */
+               if (pcibios_uninitialized_bridge_resource(bus, res)) {
+                       res->flags = 0;
+                       pr_debug("PCI:%s            (unassigned)\n", pci_name(dev));
+               } else {
+
+                       pr_debug("PCI:%s            %016llx-%016llx\n",
+                                pci_name(dev),
+                                (unsigned long long)res->start,
+                                (unsigned long long)res->end);
                }
        }
+}
+
+static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
+{
+       struct pci_dev *dev = bus->self;
+
+       pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
+
+       /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
+        * now differently between 32 and 64 bits.
+        */
+       if (dev != NULL)
+               pcibios_fixup_bridge(bus);
 
        /* Additional setup that is different between 32 and 64 bits for now */
        pcibios_do_bus_setup(bus);
index 88db4ffaf11c772e5f73ccbbca6cd96f07eb2c88..131b1dfa68c6993ff32006ae1cf22a7f0386211f 100644 (file)
@@ -53,12 +53,19 @@ LIST_HEAD(hose_list);
 
 static int pci_bus_count;
 
+/* This will remain NULL for now, until isa-bridge.c is made common
+ * to both 32-bit and 64-bit.
+ */
+struct pci_dev *isa_bridge_pcidev;
+EXPORT_SYMBOL_GPL(isa_bridge_pcidev);
+
 static void
-fixup_hide_host_resource_fsl(struct pci_devdev)
+fixup_hide_host_resource_fsl(struct pci_dev *dev)
 {
        int i, class = dev->class >> 8;
 
-       if ((class == PCI_CLASS_PROCESSOR_POWERPC) &&
+       if ((class == PCI_CLASS_PROCESSOR_POWERPC ||
+            class == PCI_CLASS_BRIDGE_OTHER) &&
                (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) &&
                (dev->bus->parent == NULL)) {
                for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
@@ -424,6 +431,7 @@ void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
        unsigned long io_offset;
        struct resource *res;
        int i;
+       struct pci_dev *dev;
 
        /* Hookup PHB resources */
        io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
@@ -457,6 +465,12 @@ void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
                        bus->resource[i+1] = res;
                }
        }
+
+       if (ppc_md.pci_dma_bus_setup)
+               ppc_md.pci_dma_bus_setup(bus);
+
+       list_for_each_entry(dev, &bus->devices, bus_list)
+               pcibios_setup_new_device(dev);
 }
 
 /* the next one is stolen from the alpha port... */
index 30eedfc5a566d4411caf634f564d5af0225d0ef5..8247cff1cb3e0dc313861d041bcf7afae3c559e4 100644 (file)
@@ -52,35 +52,6 @@ EXPORT_SYMBOL(pci_io_base);
 
 LIST_HEAD(hose_list);
 
-static struct dma_mapping_ops *pci_dma_ops;
-
-void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
-{
-       pci_dma_ops = dma_ops;
-}
-
-struct dma_mapping_ops *get_pci_dma_ops(void)
-{
-       return pci_dma_ops;
-}
-EXPORT_SYMBOL(get_pci_dma_ops);
-
-
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-       return dma_set_mask(&dev->dev, mask);
-}
-
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
-       int rc;
-
-       rc = dma_set_mask(&dev->dev, mask);
-       dev->dev.coherent_dma_mask = dev->dma_mask;
-
-       return rc;
-}
-
 static void fixup_broken_pcnet32(struct pci_dev* dev)
 {
        if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
@@ -548,26 +519,6 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
 }
 EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
-void __devinit pcibios_setup_new_device(struct pci_dev *dev)
-{
-       struct dev_archdata *sd = &dev->dev.archdata;
-
-       sd->of_node = pci_device_to_OF_node(dev);
-
-       DBG("PCI: device %s OF node: %s\n", pci_name(dev),
-           sd->of_node ? sd->of_node->full_name : "<none>");
-
-       sd->dma_ops = pci_dma_ops;
-#ifdef CONFIG_NUMA
-       sd->numa_node = pcibus_to_node(dev->bus);
-#else
-       sd->numa_node = -1;
-#endif
-       if (ppc_md.pci_dma_dev_setup)
-               ppc_md.pci_dma_dev_setup(dev);
-}
-EXPORT_SYMBOL(pcibios_setup_new_device);
-
 void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
 {
        struct pci_dev *dev;
index e1ea4fe5cfbde0a6c436978f5864f650b10928d2..8edc2359c4193f564752dfee6643512266efcc25 100644 (file)
@@ -119,6 +119,9 @@ EXPORT_SYMBOL(flush_instruction_cache);
 EXPORT_SYMBOL(flush_tlb_kernel_range);
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(_tlbie);
+#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
+EXPORT_SYMBOL(_tlbil_va);
+#endif
 #endif
 EXPORT_SYMBOL(__flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_range);
index 87d83c56b31ec1671007195ce092523535108bb9..3a2dc7e6586a392292ccf3ccbfacb39151a3f675 100644 (file)
@@ -888,9 +888,10 @@ static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
  */
 static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 {
-       cell_t *dm, *ls;
+       cell_t *dm, *ls, *usm;
        unsigned long l, n, flags;
        u64 base, size, lmb_size;
+       unsigned int is_kexec_kdump = 0, rngs;
 
        ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
        if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
@@ -905,6 +906,12 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)
        if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
                return 0;
 
+       /* check if this is a kexec/kdump kernel. */
+       usm = (cell_t *)of_get_flat_dt_prop(node, "linux,drconf-usable-memory",
+                                                &l);
+       if (usm != NULL)
+               is_kexec_kdump = 1;
+
        for (; n != 0; --n) {
                base = dt_mem_next_cell(dt_root_addr_cells, &dm);
                flags = dm[3];
@@ -915,13 +922,34 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)
                if ((flags & 0x80) || !(flags & 0x8))
                        continue;
                size = lmb_size;
-               if (iommu_is_off) {
-                       if (base >= 0x80000000ul)
+               rngs = 1;
+               if (is_kexec_kdump) {
+                       /*
+                        * For each lmb in ibm,dynamic-memory, a corresponding
+                        * entry in linux,drconf-usable-memory property contains
+                        * a counter 'p' followed by 'p' (base, size) duple.
+                        * Now read the counter from
+                        * linux,drconf-usable-memory property
+                        */
+                       rngs = dt_mem_next_cell(dt_root_size_cells, &usm);
+                       if (!rngs) /* there are no (base, size) duple */
                                continue;
-                       if ((base + size) > 0x80000000ul)
-                               size = 0x80000000ul - base;
                }
-               lmb_add(base, size);
+               do {
+                       if (is_kexec_kdump) {
+                               base = dt_mem_next_cell(dt_root_addr_cells,
+                                                        &usm);
+                               size = dt_mem_next_cell(dt_root_size_cells,
+                                                        &usm);
+                       }
+                       if (iommu_is_off) {
+                               if (base >= 0x80000000ul)
+                                       continue;
+                               if ((base + size) > 0x80000000ul)
+                                       size = 0x80000000ul - base;
+                       }
+                       lmb_add(base, size);
+               } while (--rngs);
        }
        lmb_dump_all();
        return 0;
@@ -1164,6 +1192,9 @@ void __init early_init_devtree(void *params)
 
        /* Reserve LMB regions used by kernel, initrd, dt, etc... */
        lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
+       /* If relocatable, reserve first 32k for interrupt vectors etc. */
+       if (PHYSICAL_START > MEMORY_START)
+               lmb_reserve(MEMORY_START, 0x8000);
        reserve_kdump_trampoline();
        reserve_crashkernel();
        early_reserve_mem();
index b72849ac7db39af14fe1547571da83066cdc3d77..2fdbc18ae94afe3ef27c0a32debbca2535767b7a 100644 (file)
@@ -732,7 +732,7 @@ static struct fake_elf {
                        u32     ignore_me;
                } rpadesc;
        } rpanote;
-} fake_elf = {
+} fake_elf __section(.fakeelf) = {
        .elfhdr = {
                .e_ident = { 0x7f, 'E', 'L', 'F',
                             ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
@@ -774,13 +774,13 @@ static struct fake_elf {
                .type = 0x12759999,
                .name = "IBM,RPA-Client-Config",
                .rpadesc = {
-                       .lpar_affinity = 0,
-                       .min_rmo_size = 64,     /* in megabytes */
+                       .lpar_affinity = 1,
+                       .min_rmo_size = 128,    /* in megabytes */
                        .min_rmo_percent = 0,
-                       .max_pft_size = 48,     /* 2^48 bytes max PFT size */
+                       .max_pft_size = 46,     /* 2^46 bytes max PFT size */
                        .splpar = 1,
                        .min_load = ~0U,
-                       .new_mem_def = 0
+                       .new_mem_def = 1
                }
        }
 };
@@ -1321,7 +1321,7 @@ static void __init prom_initialize_tce_table(void)
  *
  * -- Cort
  */
-extern void __secondary_hold(void);
+extern char __secondary_hold;
 extern unsigned long __secondary_hold_spinloop;
 extern unsigned long __secondary_hold_acknowledge;
 
@@ -1342,13 +1342,7 @@ static void __init prom_hold_cpus(void)
                = (void *) LOW_ADDR(__secondary_hold_spinloop);
        unsigned long *acknowledge
                = (void *) LOW_ADDR(__secondary_hold_acknowledge);
-#ifdef CONFIG_PPC64
-       /* __secondary_hold is actually a descriptor, not the text address */
-       unsigned long secondary_hold
-               = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
-#else
        unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
-#endif
 
        prom_debug("prom_hold_cpus: start...\n");
        prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
@@ -2315,13 +2309,14 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
 
 unsigned long __init prom_init(unsigned long r3, unsigned long r4,
                               unsigned long pp,
-                              unsigned long r6, unsigned long r7)
+                              unsigned long r6, unsigned long r7,
+                              unsigned long kbase)
 {      
        struct prom_t *_prom;
        unsigned long hdr;
-       unsigned long offset = reloc_offset();
 
 #ifdef CONFIG_PPC32
+       unsigned long offset = reloc_offset();
        reloc_got2(offset);
 #endif
 
@@ -2355,9 +2350,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        RELOC(of_platform) = prom_find_machine_type();
 
+#ifndef CONFIG_RELOCATABLE
        /* Bail if this is a kdump kernel. */
        if (PHYSICAL_START > 0)
                prom_panic("Error: You can't boot a kdump kernel from OF!\n");
+#endif
 
        /*
         * Check for an initrd
@@ -2377,7 +2374,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         * Copy the CPU hold code
         */
        if (RELOC(of_platform) != PLATFORM_POWERMAC)
-               copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
+               copy_and_flush(0, kbase, 0x100, 0);
 
        /*
         * Do early parsing of command line
@@ -2480,7 +2477,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        reloc_got2(-offset);
 #endif
 
-       __start(hdr, KERNELBASE + offset, 0);
+       __start(hdr, kbase, 0);
 
        return 0;
 }
diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S
new file mode 100644 (file)
index 0000000..b47a0e1
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Code to process dynamic relocations in the kernel.
+ *
+ * Copyright 2008 Paul Mackerras, IBM Corp.
+ *
+ *  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 <asm/ppc_asm.h>
+
+RELA = 7
+RELACOUNT = 0x6ffffff9
+R_PPC64_RELATIVE = 22
+
+/*
+ * r3 = desired final address of kernel
+ */
+_GLOBAL(relocate)
+       mflr    r0
+       bcl     20,31,$+4
+0:     mflr    r12             /* r12 has runtime addr of label 0 */
+       mtlr    r0
+       ld      r11,(p_dyn - 0b)(r12)
+       add     r11,r11,r12     /* r11 has runtime addr of .dynamic section */
+       ld      r9,(p_rela - 0b)(r12)
+       add     r9,r9,r12       /* r9 has runtime addr of .rela.dyn section */
+       ld      r10,(p_st - 0b)(r12)
+       add     r10,r10,r12     /* r10 has runtime addr of _stext */
+
+       /*
+        * Scan the dynamic section for the RELA and RELACOUNT entries.
+        */
+       li      r7,0
+       li      r8,0
+1:     ld      r6,0(r11)       /* get tag */
+       cmpdi   r6,0
+       beq     4f              /* end of list */
+       cmpdi   r6,RELA
+       bne     2f
+       ld      r7,8(r11)       /* get RELA pointer in r7 */
+       b       3f
+2:     addis   r6,r6,(-RELACOUNT)@ha
+       cmpdi   r6,RELACOUNT@l
+       bne     3f
+       ld      r8,8(r11)       /* get RELACOUNT value in r8 */
+3:     addi    r11,r11,16
+       b       1b
+4:     cmpdi   r7,0            /* check we have both RELA and RELACOUNT */
+       cmpdi   cr1,r8,0
+       beq     6f
+       beq     cr1,6f
+
+       /*
+        * Work out linktime address of _stext and hence the
+        * relocation offset to be applied.
+        * cur_offset [r7] = rela.run [r9] - rela.link [r7]
+        * _stext.link [r10] = _stext.run [r10] - cur_offset [r7]
+        * final_offset [r3] = _stext.final [r3] - _stext.link [r10]
+        */
+       subf    r7,r7,r9        /* cur_offset */
+       subf    r10,r7,r10
+       subf    r3,r10,r3       /* final_offset */
+
+       /*
+        * Run through the list of relocations and process the
+        * R_PPC64_RELATIVE ones.
+        */
+       mtctr   r8
+5:     lwz     r0,12(9)        /* ELF64_R_TYPE(reloc->r_info) */
+       cmpwi   r0,R_PPC64_RELATIVE
+       bne     6f
+       ld      r6,0(r9)        /* reloc->r_offset */
+       ld      r0,16(r9)       /* reloc->r_addend */
+       add     r0,r0,r3
+       stdx    r0,r7,r6
+       addi    r9,r9,24
+       bdnz    5b
+
+6:     blr
+
+p_dyn: .llong  __dynamic_start - 0b
+p_rela:        .llong  __rela_dyn_start - 0b
+p_st:  .llong  _stext - 0b
+
index 9cc5a52711e5b585bf78ee2e3934e94405508707..5ec56ff03e8621584cf026b2fdbb0405dddd84b0 100644 (file)
@@ -254,8 +254,21 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        /* If we are a Freescale core do a simple check so
         * we dont have to keep adding cases in the future */
        if (PVR_VER(pvr) & 0x8000) {
-               maj = PVR_MAJ(pvr);
-               min = PVR_MIN(pvr);
+               switch (PVR_VER(pvr)) {
+               case 0x8000:    /* 7441/7450/7451, Voyager */
+               case 0x8001:    /* 7445/7455, Apollo 6 */
+               case 0x8002:    /* 7447/7457, Apollo 7 */
+               case 0x8003:    /* 7447A, Apollo 7 PM */
+               case 0x8004:    /* 7448, Apollo 8 */
+               case 0x800c:    /* 7410, Nitro */
+                       maj = ((pvr >> 8) & 0xF);
+                       min = PVR_MIN(pvr);
+                       break;
+               default:        /* e500/book-e */
+                       maj = PVR_MAJ(pvr);
+                       min = PVR_MIN(pvr);
+                       break;
+               }
        } else {
                switch (PVR_VER(pvr)) {
                        case 0x0020:    /* 403 family */
index 066e65c59b58230091db2145e1e4115abe541b84..c1a27626a940d1b49c990bbcc3f3f2c5f538b097 100644 (file)
@@ -111,7 +111,7 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
  * This is called very early on the boot process, after a minimal
  * MMU environment has been set up but before MMU_init is called.
  */
-notrace void __init machine_init(unsigned long dt_ptr, unsigned long phys)
+notrace void __init machine_init(unsigned long dt_ptr)
 {
        /* Enable early debugging if any specified (see udbg.h) */
        udbg_early_init();
@@ -209,23 +209,12 @@ EXPORT_SYMBOL(nvram_sync);
 
 #endif /* CONFIG_NVRAM */
 
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
 int __init ppc_init(void)
 {
-       int cpu;
-
        /* clear the progress line */
        if (ppc_md.progress)
                ppc_md.progress("             ", 0xffff);
 
-       /* register CPU devices */
-       for_each_possible_cpu(cpu) {
-               struct cpu *c = &per_cpu(cpu_devices, cpu);
-               c->hotpluggable = 1;
-               register_cpu(c, cpu);
-       }
-
        /* call platform init */
        if (ppc_md.init != NULL) {
                ppc_md.init();
index 8b25f51f03bf9b8fc78da61015859a4ce9585fd0..843c0af210d0f7f0161b8583c50b71a90604faf0 100644 (file)
@@ -255,9 +255,11 @@ void early_setup_secondary(void)
 #endif /* CONFIG_SMP */
 
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+extern unsigned long __secondary_hold_spinloop;
+extern void generic_secondary_smp_init(void);
+
 void smp_release_cpus(void)
 {
-       extern unsigned long __secondary_hold_spinloop;
        unsigned long *ptr;
 
        DBG(" -> smp_release_cpus()\n");
@@ -266,12 +268,11 @@ void smp_release_cpus(void)
         * all now so they can start to spin on their individual paca
         * spinloops. For non SMP kernels, the secondary cpus never get out
         * of the common spinloop.
-        * This is useless but harmless on iSeries, secondaries are already
-        * waiting on their paca spinloops. */
+        */
 
        ptr  = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
                        - PHYSICAL_START);
-       *ptr = 1;
+       *ptr = __pa(generic_secondary_smp_init);
        mb();
 
        DBG(" <- smp_release_cpus()\n");
index c27b10a1bd79adffe0a2686b9c5baaf34d3eb724..ff9f7010097d1568943329a15d8c04458beddc4c 100644 (file)
@@ -101,8 +101,7 @@ void smp_message_recv(int msg)
                generic_smp_call_function_interrupt();
                break;
        case PPC_MSG_RESCHEDULE:
-               /* XXX Do we have to do this? */
-               set_need_resched();
+               /* we notice need_resched on exit */
                break;
        case PPC_MSG_CALL_FUNC_SINGLE:
                generic_smp_call_function_single_interrupt();
index e092c3cbdb9b978ac3f7a9123375e07769e0aab5..86ac1d90d02bcb3d80060d7531da58022f685987 100644 (file)
@@ -133,7 +133,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 
        cmpdi   r12,0
        beq-    nothing_to_copy
-       li      r15,512
+       li      r15,PAGE_SIZE>>3
 copyloop:
        ld      r13,pbe_address(r12)
        ld      r14,pbe_orig_address(r12)
index d98634c76060e735290c03f0fabff5d635437e8c..bb1cfcfdbbbbc02e73c4c5292b900e6f7a86c8f8 100644 (file)
@@ -61,42 +61,6 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
        return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x));
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
-       compat_ino_t ino;
-       long err;
-
-       if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
-           !new_valid_dev(stat->rdev))
-               return -EOVERFLOW;
-
-       ino = stat->ino;
-       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
-               return -EOVERFLOW;
-
-       err  = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
-       err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-       err |= __put_user(ino, &statbuf->st_ino);
-       err |= __put_user(stat->mode, &statbuf->st_mode);
-       err |= __put_user(stat->nlink, &statbuf->st_nlink);
-       err |= __put_user(stat->uid, &statbuf->st_uid);
-       err |= __put_user(stat->gid, &statbuf->st_gid);
-       err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
-       err |= __put_user(stat->size, &statbuf->st_size);
-       err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
-       err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-       err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-       err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-       err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-       err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-       err |= __put_user(stat->blksize, &statbuf->st_blksize);
-       err |= __put_user(stat->blocks, &statbuf->st_blocks);
-       err |= __put_user(0, &statbuf->__unused4[0]);
-       err |= __put_user(0, &statbuf->__unused4[1]);
-
-       return err;
-}
-
 /* Note: it is necessary to treat option as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -107,77 +71,6 @@ asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
        return sys_sysfs((int)option, arg1, arg2);
 }
 
-asmlinkage long compat_sys_pause(void)
-{
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       
-       return -ERESTARTNOHAND;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) |
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-
-
-
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-extern struct timezone sys_tz;
-
-asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       
-       return 0;
-}
-
-
-
-asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-       
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 #ifdef CONFIG_SYSVIPC
 long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
               u32 fifth)
index 56d172d16e5654b483e2ddaa087c9c6302e6e42d..86a2ffccef2592066ece036093a4e0b73858f7da 100644 (file)
 #include <asm/firmware.h>
 #include <asm/hvcall.h>
 #include <asm/prom.h>
-#include <asm/paca.h>
-#include <asm/lppaca.h>
 #include <asm/machdep.h>
 #include <asm/smp.h>
 
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+#include <asm/lppaca.h>
+#endif
+
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
 static DEFINE_PER_CPU(struct kobject *, cache_toplevel);
 
-/* SMT stuff */
+/*
+ * SMT snooze delay stuff, 64-bit only for now
+ */
+
+#ifdef CONFIG_PPC64
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
 /* Time in microseconds we delay before sleeping in the idle loop */
 DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
 
@@ -106,7 +112,7 @@ static int __init setup_smt_snooze_delay(char *str)
 }
 __setup("smt-snooze-delay=", setup_smt_snooze_delay);
 
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_PPC64 */
 
 /*
  * Enabling PMCs will slow partition context switch times so we only do
@@ -115,7 +121,7 @@ __setup("smt-snooze-delay=", setup_smt_snooze_delay);
 
 static DEFINE_PER_CPU(char, pmcs_enabled);
 
-void ppc64_enable_pmcs(void)
+void ppc_enable_pmcs(void)
 {
        /* Only need to enable them once */
        if (__get_cpu_var(pmcs_enabled))
@@ -126,8 +132,9 @@ void ppc64_enable_pmcs(void)
        if (ppc_md.enable_pmcs)
                ppc_md.enable_pmcs();
 }
-EXPORT_SYMBOL(ppc64_enable_pmcs);
+EXPORT_SYMBOL(ppc_enable_pmcs);
 
+#if defined(CONFIG_6xx) || defined(CONFIG_PPC64)
 /* XXX convert to rusty's on_one_cpu */
 static unsigned long run_on_cpu(unsigned long cpu,
                                unsigned long (*func)(unsigned long),
@@ -146,6 +153,7 @@ static unsigned long run_on_cpu(unsigned long cpu,
 
        return ret;
 }
+#endif
 
 #define SYSFS_PMCSETUP(NAME, ADDRESS) \
 static unsigned long read_##NAME(unsigned long junk) \
@@ -154,7 +162,7 @@ static unsigned long read_##NAME(unsigned long junk) \
 } \
 static unsigned long write_##NAME(unsigned long val) \
 { \
-       ppc64_enable_pmcs(); \
+       ppc_enable_pmcs(); \
        mtspr(ADDRESS, val); \
        return 0; \
 } \
@@ -184,28 +192,53 @@ static ssize_t __used \
  * that are implemented on the current processor
  */
 
+#if defined(CONFIG_PPC64)
+#define HAS_PPC_PMC_CLASSIC    1
+#define HAS_PPC_PMC_IBM                1
+#define HAS_PPC_PMC_PA6T       1
+#elif defined(CONFIG_6xx)
+#define HAS_PPC_PMC_CLASSIC    1
+#define HAS_PPC_PMC_IBM                1
+#define HAS_PPC_PMC_G4         1
+#endif
+
+
+#ifdef HAS_PPC_PMC_CLASSIC
 SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0);
 SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1);
-SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
 SYSFS_PMCSETUP(pmc1, SPRN_PMC1);
 SYSFS_PMCSETUP(pmc2, SPRN_PMC2);
 SYSFS_PMCSETUP(pmc3, SPRN_PMC3);
 SYSFS_PMCSETUP(pmc4, SPRN_PMC4);
 SYSFS_PMCSETUP(pmc5, SPRN_PMC5);
 SYSFS_PMCSETUP(pmc6, SPRN_PMC6);
+
+#ifdef HAS_PPC_PMC_G4
+SYSFS_PMCSETUP(mmcr2, SPRN_MMCR2);
+#endif
+
+#ifdef CONFIG_PPC64
 SYSFS_PMCSETUP(pmc7, SPRN_PMC7);
 SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
+
+SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
 SYSFS_PMCSETUP(purr, SPRN_PURR);
 SYSFS_PMCSETUP(spurr, SPRN_SPURR);
 SYSFS_PMCSETUP(dscr, SPRN_DSCR);
 
+static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
+static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
+static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
+static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
+#endif /* CONFIG_PPC64 */
+
+#ifdef HAS_PPC_PMC_PA6T
 SYSFS_PMCSETUP(pa6t_pmc0, SPRN_PA6T_PMC0);
 SYSFS_PMCSETUP(pa6t_pmc1, SPRN_PA6T_PMC1);
 SYSFS_PMCSETUP(pa6t_pmc2, SPRN_PA6T_PMC2);
 SYSFS_PMCSETUP(pa6t_pmc3, SPRN_PA6T_PMC3);
 SYSFS_PMCSETUP(pa6t_pmc4, SPRN_PA6T_PMC4);
 SYSFS_PMCSETUP(pa6t_pmc5, SPRN_PA6T_PMC5);
-
 #ifdef CONFIG_DEBUG_KERNEL
 SYSFS_PMCSETUP(hid0, SPRN_HID0);
 SYSFS_PMCSETUP(hid1, SPRN_HID1);
@@ -236,28 +269,37 @@ SYSFS_PMCSETUP(tsr1, SPRN_PA6T_TSR1);
 SYSFS_PMCSETUP(tsr2, SPRN_PA6T_TSR2);
 SYSFS_PMCSETUP(tsr3, SPRN_PA6T_TSR3);
 #endif /* CONFIG_DEBUG_KERNEL */
+#endif /* HAS_PPC_PMC_PA6T */
 
-static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
-static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
-static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
-static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
-
+#ifdef HAS_PPC_PMC_IBM
 static struct sysdev_attribute ibm_common_attrs[] = {
        _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
        _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
 };
+#endif /* HAS_PPC_PMC_G4 */
+
+#ifdef HAS_PPC_PMC_G4
+static struct sysdev_attribute g4_common_attrs[] = {
+       _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
+       _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
+       _SYSDEV_ATTR(mmcr2, 0600, show_mmcr2, store_mmcr2),
+};
+#endif /* HAS_PPC_PMC_G4 */
 
-static struct sysdev_attribute ibm_pmc_attrs[] = {
+static struct sysdev_attribute classic_pmc_attrs[] = {
        _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1),
        _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2),
        _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3),
        _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4),
        _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5),
        _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6),
+#ifdef CONFIG_PPC64
        _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7),
        _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8),
+#endif
 };
 
+#ifdef HAS_PPC_PMC_PA6T
 static struct sysdev_attribute pa6t_attrs[] = {
        _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0),
        _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1),
@@ -298,6 +340,8 @@ static struct sysdev_attribute pa6t_attrs[] = {
        _SYSDEV_ATTR(tsr3, 0600, show_tsr3, store_tsr3),
 #endif /* CONFIG_DEBUG_KERNEL */
 };
+#endif /* HAS_PPC_PMC_PA6T */
+#endif /* HAS_PPC_PMC_CLASSIC */
 
 struct cache_desc {
        struct kobject kobj;
@@ -588,23 +632,36 @@ static void __cpuinit register_cpu_online(unsigned int cpu)
        struct sysdev_attribute *attrs, *pmc_attrs;
        int i, nattrs;
 
+#ifdef CONFIG_PPC64
        if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
                        cpu_has_feature(CPU_FTR_SMT))
                sysdev_create_file(s, &attr_smt_snooze_delay);
+#endif
 
        /* PMC stuff */
        switch (cur_cpu_spec->pmc_type) {
+#ifdef HAS_PPC_PMC_IBM
        case PPC_PMC_IBM:
                attrs = ibm_common_attrs;
                nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute);
-               pmc_attrs = ibm_pmc_attrs;
+               pmc_attrs = classic_pmc_attrs;
                break;
+#endif /* HAS_PPC_PMC_IBM */
+#ifdef HAS_PPC_PMC_G4
+       case PPC_PMC_G4:
+               attrs = g4_common_attrs;
+               nattrs = sizeof(g4_common_attrs) / sizeof(struct sysdev_attribute);
+               pmc_attrs = classic_pmc_attrs;
+               break;
+#endif /* HAS_PPC_PMC_G4 */
+#ifdef HAS_PPC_PMC_PA6T
        case PPC_PMC_PA6T:
                /* PA Semi starts counting at PMC0 */
                attrs = pa6t_attrs;
                nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute);
                pmc_attrs = NULL;
                break;
+#endif /* HAS_PPC_PMC_PA6T */
        default:
                attrs = NULL;
                nattrs = 0;
@@ -618,6 +675,7 @@ static void __cpuinit register_cpu_online(unsigned int cpu)
                for (i = 0; i < cur_cpu_spec->num_pmcs; i++)
                        sysdev_create_file(s, &pmc_attrs[i]);
 
+#ifdef CONFIG_PPC64
        if (cpu_has_feature(CPU_FTR_MMCRA))
                sysdev_create_file(s, &attr_mmcra);
 
@@ -629,6 +687,7 @@ static void __cpuinit register_cpu_online(unsigned int cpu)
 
        if (cpu_has_feature(CPU_FTR_DSCR))
                sysdev_create_file(s, &attr_dscr);
+#endif /* CONFIG_PPC64 */
 
        create_cache_info(s);
 }
@@ -641,16 +700,9 @@ static void remove_cache_info(struct sys_device *sysdev)
        int cpu = sysdev->id;
 
        cache_desc = per_cpu(cache_desc, cpu);
-       if (cache_desc != NULL) {
-               sysfs_remove_file(&cache_desc->kobj, &cache_size_attr.attr);
-               sysfs_remove_file(&cache_desc->kobj, &cache_line_size_attr.attr);
-               sysfs_remove_file(&cache_desc->kobj, &cache_type_attr.attr);
-               sysfs_remove_file(&cache_desc->kobj, &cache_level_attr.attr);
-               sysfs_remove_file(&cache_desc->kobj, &cache_nr_sets_attr.attr);
-               sysfs_remove_file(&cache_desc->kobj, &cache_assoc_attr.attr);
-
+       if (cache_desc != NULL)
                kobject_put(&cache_desc->kobj);
-       }
+
        cache_toplevel = per_cpu(cache_toplevel, cpu);
        if (cache_toplevel != NULL)
                kobject_put(cache_toplevel);
@@ -671,17 +723,28 @@ static void unregister_cpu_online(unsigned int cpu)
 
        /* PMC stuff */
        switch (cur_cpu_spec->pmc_type) {
+#ifdef HAS_PPC_PMC_IBM
        case PPC_PMC_IBM:
                attrs = ibm_common_attrs;
                nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute);
-               pmc_attrs = ibm_pmc_attrs;
+               pmc_attrs = classic_pmc_attrs;
+               break;
+#endif /* HAS_PPC_PMC_IBM */
+#ifdef HAS_PPC_PMC_G4
+       case PPC_PMC_G4:
+               attrs = g4_common_attrs;
+               nattrs = sizeof(g4_common_attrs) / sizeof(struct sysdev_attribute);
+               pmc_attrs = classic_pmc_attrs;
                break;
+#endif /* HAS_PPC_PMC_G4 */
+#ifdef HAS_PPC_PMC_PA6T
        case PPC_PMC_PA6T:
                /* PA Semi starts counting at PMC0 */
                attrs = pa6t_attrs;
                nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute);
                pmc_attrs = NULL;
                break;
+#endif /* HAS_PPC_PMC_PA6T */
        default:
                attrs = NULL;
                nattrs = 0;
@@ -695,6 +758,7 @@ static void unregister_cpu_online(unsigned int cpu)
                for (i = 0; i < cur_cpu_spec->num_pmcs; i++)
                        sysdev_remove_file(s, &pmc_attrs[i]);
 
+#ifdef CONFIG_PPC64
        if (cpu_has_feature(CPU_FTR_MMCRA))
                sysdev_remove_file(s, &attr_mmcra);
 
@@ -706,6 +770,7 @@ static void unregister_cpu_online(unsigned int cpu)
 
        if (cpu_has_feature(CPU_FTR_DSCR))
                sysdev_remove_file(s, &attr_dscr);
+#endif /* CONFIG_PPC64 */
 
        remove_cache_info(s);
 }
index 2750fbab1975b2e7e4c84d48a67589385aeb9e40..434c92a85c037431512e96f16b4e9ea49265a6c6 100644 (file)
@@ -1232,7 +1232,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
        else
                viodev->dev.archdata.dma_ops = &dma_iommu_ops;
        viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev);
-       viodev->dev.archdata.numa_node = of_node_to_nid(of_node);
+       set_dev_node(&viodev->dev, of_node_to_nid(of_node));
 
        /* init generic 'struct device' fields: */
        viodev->dev.parent = &vio_bus_device.dev;
index 9f6c1ca1739e08ecc1e56a64ffed6c6a610a3e1a..b39c27ed79196c2d7cd1d4f32843fd3ee5563581 100644 (file)
@@ -187,6 +187,24 @@ SECTIONS
                *(.machine.desc)
                __machine_desc_end = . ;
        }
+       . = ALIGN(8);
+       .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) { *(.dynsym) }
+       .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
+       .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
+       {
+               __dynamic_start = .;
+               *(.dynamic)
+       }
+       .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
+       .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
+       .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
+       {
+               __rela_dyn_start = .;
+               *(.rela*)
+       }
+
+       /* Fake ELF header containing RPA note; for addnote */
+       .fakeelf : AT(ADDR(.fakeelf) - LOAD_OFFSET) { *(.fakeelf) }
 
        /* freed after init ends here */
        . = ALIGN(PAGE_SIZE);
index f9837f44ac0bac2c2ba8d6c81b5f9eeb735b431b..75f3267fdc300977f26ac6cc6e2a0db41add6525 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ * Copyright (C) 2008 Mark Nelson, IBM Corp.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  */
 #include <asm/processor.h>
 #include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+        .section        ".toc","aw"
+PPC64_CACHES:
+        .tc             ppc64_caches[TC],ppc64_caches
+        .section        ".text"
+
 
 _GLOBAL(copy_4K_page)
-       std     r31,-8(1)
-       std     r30,-16(1)
-       std     r29,-24(1)
-       std     r28,-32(1)
-       std     r27,-40(1)
-       std     r26,-48(1)
-       std     r25,-56(1)
-       std     r24,-64(1)
-       std     r23,-72(1)
-       std     r22,-80(1)
-       std     r21,-88(1)
-       std     r20,-96(1)
-       li      r5,4096/32 - 1
+       li      r5,4096         /* 4K page size */
+BEGIN_FTR_SECTION
+       ld      r10,PPC64_CACHES@toc(r2)
+       lwz     r11,DCACHEL1LOGLINESIZE(r10)    /* log2 of cache line size */
+       lwz     r12,DCACHEL1LINESIZE(r10)       /* get cache line size */
+       li      r9,0
+       srd     r8,r5,r11
+
+       mtctr   r8
+setup:
+       dcbt    r9,r4
+       dcbz    r9,r3
+       add     r9,r9,r12
+       bdnz    setup
+END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
        addi    r3,r3,-8
-       li      r12,5
-0:     addi    r5,r5,-24
-       mtctr   r12
-       ld      r22,640(4)
-       ld      r21,512(4)
-       ld      r20,384(4)
-       ld      r11,256(4)
-       ld      r9,128(4)
-       ld      r7,0(4)
-       ld      r25,648(4)
-       ld      r24,520(4)
-       ld      r23,392(4)
-       ld      r10,264(4)
-       ld      r8,136(4)
-       ldu     r6,8(4)
-       cmpwi   r5,24
-1:     std     r22,648(3)
-       std     r21,520(3)
-       std     r20,392(3)
-       std     r11,264(3)
-       std     r9,136(3)
-       std     r7,8(3)
-       ld      r28,648(4)
-       ld      r27,520(4)
-       ld      r26,392(4)
-       ld      r31,264(4)
-       ld      r30,136(4)
-       ld      r29,8(4)
-       std     r25,656(3)
-       std     r24,528(3)
-       std     r23,400(3)
-       std     r10,272(3)
-       std     r8,144(3)
-       std     r6,16(3)
-       ld      r22,656(4)
-       ld      r21,528(4)
-       ld      r20,400(4)
-       ld      r11,272(4)
-       ld      r9,144(4)
-       ld      r7,16(4)
-       std     r28,664(3)
-       std     r27,536(3)
-       std     r26,408(3)
-       std     r31,280(3)
-       std     r30,152(3)
-       stdu    r29,24(3)
-       ld      r25,664(4)
-       ld      r24,536(4)
-       ld      r23,408(4)
-       ld      r10,280(4)
-       ld      r8,152(4)
-       ldu     r6,24(4)
+       srdi    r8,r5,7         /* page is copied in 128 byte strides */
+       addi    r8,r8,-1        /* one stride copied outside loop */
+
+       mtctr   r8
+
+       ld      r5,0(r4)
+       ld      r6,8(r4)
+       ld      r7,16(r4)
+       ldu     r8,24(r4)
+1:     std     r5,8(r3)
+       ld      r9,8(r4)
+       std     r6,16(r3)
+       ld      r10,16(r4)
+       std     r7,24(r3)
+       ld      r11,24(r4)
+       std     r8,32(r3)
+       ld      r12,32(r4)
+       std     r9,40(r3)
+       ld      r5,40(r4)
+       std     r10,48(r3)
+       ld      r6,48(r4)
+       std     r11,56(r3)
+       ld      r7,56(r4)
+       std     r12,64(r3)
+       ld      r8,64(r4)
+       std     r5,72(r3)
+       ld      r9,72(r4)
+       std     r6,80(r3)
+       ld      r10,80(r4)
+       std     r7,88(r3)
+       ld      r11,88(r4)
+       std     r8,96(r3)
+       ld      r12,96(r4)
+       std     r9,104(r3)
+       ld      r5,104(r4)
+       std     r10,112(r3)
+       ld      r6,112(r4)
+       std     r11,120(r3)
+       ld      r7,120(r4)
+       stdu    r12,128(r3)
+       ldu     r8,128(r4)
        bdnz    1b
-       std     r22,648(3)
-       std     r21,520(3)
-       std     r20,392(3)
-       std     r11,264(3)
-       std     r9,136(3)
-       std     r7,8(3)
-       addi    r4,r4,640
-       addi    r3,r3,648
-       bge     0b
-       mtctr   r5
-       ld      r7,0(4)
-       ld      r8,8(4)
-       ldu     r9,16(4)
-3:     ld      r10,8(4)
-       std     r7,8(3)
-       ld      r7,16(4)
-       std     r8,16(3)
-       ld      r8,24(4)
-       std     r9,24(3)
-       ldu     r9,32(4)
-       stdu    r10,32(3)
-       bdnz    3b
-4:     ld      r10,8(4)
-       std     r7,8(3)
-       std     r8,16(3)
-       std     r9,24(3)
-       std     r10,32(3)
-9:     ld      r20,-96(1)
-       ld      r21,-88(1)
-       ld      r22,-80(1)
-       ld      r23,-72(1)
-       ld      r24,-64(1)
-       ld      r25,-56(1)
-       ld      r26,-48(1)
-       ld      r27,-40(1)
-       ld      r28,-32(1)
-       ld      r29,-24(1)
-       ld      r30,-16(1)
-       ld      r31,-8(1)
+
+       std     r5,8(r3)
+       ld      r9,8(r4)
+       std     r6,16(r3)
+       ld      r10,16(r4)
+       std     r7,24(r3)
+       ld      r11,24(r4)
+       std     r8,32(r3)
+       ld      r12,32(r4)
+       std     r9,40(r3)
+       ld      r5,40(r4)
+       std     r10,48(r3)
+       ld      r6,48(r4)
+       std     r11,56(r3)
+       ld      r7,56(r4)
+       std     r12,64(r3)
+       ld      r8,64(r4)
+       std     r5,72(r3)
+       ld      r9,72(r4)
+       std     r6,80(r3)
+       ld      r10,80(r4)
+       std     r7,88(r3)
+       ld      r11,88(r4)
+       std     r8,96(r3)
+       ld      r12,96(r4)
+       std     r9,104(r3)
+       std     r10,112(r3)
+       std     r11,120(r3)
+       std     r12,128(r3)
        blr
index 5d83907f6591dbf9cf68b32dbceaa99ddaf3563e..31734c0969cd28014b226f300f0b1932186ea4e1 100644 (file)
@@ -203,7 +203,7 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
                /*
                 * Set the "dma handle"
                 */
-               *handle = page_to_bus(page);
+               *handle = page_to_phys(page);
 
                do {
                        BUG_ON(!pte_none(*pte));
index 29bc9126241b1d9893acf6d51024a6f6797efa19..03aa98dd9f0a5c0b1a6f564bd9a658d2260620cc 100644 (file)
@@ -4,13 +4,14 @@ obj-y                         := math.o fmr.o lfd.o stfd.o
 obj-$(CONFIG_MATH_EMULATION)   += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
                                        fctiw.o fctiwz.o fdiv.o fdivs.o \
                                        fmadd.o fmadds.o fmsub.o fmsubs.o \
-                                       fmul.o fmuls.o fnabs.o fneg.o types.o \
+                                       fmul.o fmuls.o fnabs.o fneg.o \
                                        fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \
                                        fres.o frsp.o frsqrte.o fsel.o lfs.o \
                                        fsqrt.o fsqrts.o fsub.o fsubs.o \
                                        mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
-                                       mtfsf.o mtfsfi.o stfiwx.o stfs.o \
-                                       udivmodti4.o
+                                       mtfsf.o mtfsfi.o stfiwx.o stfs.o
 
 CFLAGS_fabs.o = -fno-builtin-fabs
 CFLAGS_math.o = -fno-builtin-fabs
+
+EXTRA_CFLAGS = -I. -Iinclude/math-emu -w
diff --git a/arch/powerpc/math-emu/double.h b/arch/powerpc/math-emu/double.h
deleted file mode 100644 (file)
index ffba8b6..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Definitions for IEEE Double Precision
- */
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel kid.  Go buy yourself a real computer."
-#endif
-
-#if _FP_W_TYPE_SIZE < 64
-#define _FP_FRACTBITS_D                (2 * _FP_W_TYPE_SIZE)
-#else
-#define _FP_FRACTBITS_D                _FP_W_TYPE_SIZE
-#endif
-
-#define _FP_FRACBITS_D         53
-#define _FP_FRACXBITS_D                (_FP_FRACTBITS_D - _FP_FRACBITS_D)
-#define _FP_WFRACBITS_D                (_FP_WORKBITS + _FP_FRACBITS_D)
-#define _FP_WFRACXBITS_D       (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
-#define _FP_EXPBITS_D          11
-#define _FP_EXPBIAS_D          1023
-#define _FP_EXPMAX_D           2047
-
-#define _FP_QNANBIT_D          \
-       ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE))
-#define _FP_IMPLBIT_D          \
-       ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE))
-#define _FP_OVERFLOW_D         \
-       ((_FP_W_TYPE)1 << (_FP_WFRACBITS_D % _FP_W_TYPE_SIZE))
-
-#if _FP_W_TYPE_SIZE < 64
-
-union _FP_UNION_D
-{
-  double flt;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign  : 1;
-    unsigned exp   : _FP_EXPBITS_D;
-    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
-    unsigned frac0 : _FP_W_TYPE_SIZE;
-#else
-    unsigned frac0 : _FP_W_TYPE_SIZE;
-    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
-    unsigned exp   : _FP_EXPBITS_D;
-    unsigned sign  : 1;
-#endif
-  } bits __attribute__((packed));
-};
-
-#define FP_DECL_D(X)           _FP_DECL(2,X)
-#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
-#define FP_PACK_RAW_D(val,X)   _FP_PACK_RAW_2(D,val,X)
-
-#define FP_UNPACK_D(X,val)             \
-  do {                                 \
-    _FP_UNPACK_RAW_2(D,X,val);         \
-    _FP_UNPACK_CANONICAL(D,2,X);       \
-  } while (0)
-
-#define FP_PACK_D(val,X)               \
-  do {                                 \
-    _FP_PACK_CANONICAL(D,2,X);         \
-    _FP_PACK_RAW_2(D,val,X);           \
-  } while (0)
-
-#define FP_NEG_D(R,X)          _FP_NEG(D,2,R,X)
-#define FP_ADD_D(R,X,Y)                _FP_ADD(D,2,R,X,Y)
-#define FP_SUB_D(R,X,Y)                _FP_SUB(D,2,R,X,Y)
-#define FP_MUL_D(R,X,Y)                _FP_MUL(D,2,R,X,Y)
-#define FP_DIV_D(R,X,Y)                _FP_DIV(D,2,R,X,Y)
-#define FP_SQRT_D(R,X)         _FP_SQRT(D,2,R,X)
-
-#define FP_CMP_D(r,X,Y,un)     _FP_CMP(D,2,r,X,Y,un)
-#define FP_CMP_EQ_D(r,X,Y)     _FP_CMP_EQ(D,2,r,X,Y)
-
-#define FP_TO_INT_D(r,X,rsz,rsg)  _FP_TO_INT(D,2,r,X,rsz,rsg)
-#define FP_FROM_INT_D(X,r,rs,rt)  _FP_FROM_INT(D,2,X,r,rs,rt)
-
-#else
-
-union _FP_UNION_D
-{
-  double flt;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign : 1;
-    unsigned exp  : _FP_EXPBITS_D;
-    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
-#else
-    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
-    unsigned exp  : _FP_EXPBITS_D;
-    unsigned sign : 1;
-#endif
-  } bits __attribute__((packed));
-};
-
-#define FP_DECL_D(X)           _FP_DECL(1,X)
-#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
-#define FP_PACK_RAW_D(val,X)   _FP_PACK_RAW_1(D,val,X)
-
-#define FP_UNPACK_D(X,val)             \
-  do {                                 \
-    _FP_UNPACK_RAW_1(D,X,val);         \
-    _FP_UNPACK_CANONICAL(D,1,X);       \
-  } while (0)
-
-#define FP_PACK_D(val,X)               \
-  do {                                 \
-    _FP_PACK_CANONICAL(D,1,X);         \
-    _FP_PACK_RAW_1(D,val,X);           \
-  } while (0)
-
-#define FP_NEG_D(R,X)          _FP_NEG(D,1,R,X)
-#define FP_ADD_D(R,X,Y)                _FP_ADD(D,1,R,X,Y)
-#define FP_SUB_D(R,X,Y)                _FP_SUB(D,1,R,X,Y)
-#define FP_MUL_D(R,X,Y)                _FP_MUL(D,1,R,X,Y)
-#define FP_DIV_D(R,X,Y)                _FP_DIV(D,1,R,X,Y)
-#define FP_SQRT_D(R,X)         _FP_SQRT(D,1,R,X)
-
-/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
-   the target machine.  */
-
-#define FP_CMP_D(r,X,Y,un)     _FP_CMP(D,1,r,X,Y,un)
-#define FP_CMP_EQ_D(r,X,Y)     _FP_CMP_EQ(D,1,r,X,Y)
-
-#define FP_TO_INT_D(r,X,rsz,rsg)  _FP_TO_INT(D,1,r,X,rsz,rsg)
-#define FP_FROM_INT_D(X,r,rs,rt)  _FP_FROM_INT(D,1,X,r,rs,rt)
-
-#endif /* W_TYPE_SIZE < 64 */
index 7befbbf2c3323c5803bbaa6d5da5ac3d3ad6f433..04d3b4aa32cedb9ab75801aaa6b21a5019118a98 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fadd(void *frD, void *frA, void *frB)
@@ -11,28 +12,28 @@ fadd(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
        printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
 #endif
 
-       if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
-               ret |= EFLAG_VXISI;
-
        FP_ADD_D(R, A, B);
 
 #ifdef DEBUG
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 2b346b38b4805298d12c74edb7e63d77d9ecb68c..5930f40a868743dfb0683350bc2f2e789aa6d9ea 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fadds(void *frD, void *frA, void *frB)
@@ -12,28 +13,27 @@ fadds(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
-       int ret = 0;
+       FP_DECL_EX;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
        printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
 #endif
 
-       if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
-               ret |= EFLAG_VXISI;
-
        FP_ADD_D(R, A, B);
 
 #ifdef DEBUG
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 36d689044c63ad4e0a42a5084241017dfbfd50c9..b5dc4498cd71023dfdc237f79415b1043901f36b 100644 (file)
@@ -2,14 +2,16 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
 {
        FP_DECL_D(A);
        FP_DECL_D(B);
+       FP_DECL_EX;
        int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
        long cmp;
        int ret = 0;
@@ -18,8 +20,8 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
        printk("%s: %p (%08x) %d %p %p\n", __func__, ccr, *ccr, crfD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
index 53d93894f2a692d00ebaac71d4014bb8e0fc4356..d4fb1babc6ada6abdaa069934f9f9f48ff73f136 100644 (file)
@@ -2,14 +2,16 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
 {
        FP_DECL_D(A);
        FP_DECL_D(B);
+       FP_DECL_EX;
        int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
        long cmp;
 
@@ -17,8 +19,8 @@ fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
        printk("%s: %p (%08x) %d %p %p\n", __func__, ccr, *ccr, crfD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
index fcd7a95e021dcb5b9711115c57830ceeefaeefef..f694440ddc003a276ef5630f4ad3d5b259a18cc4 100644 (file)
@@ -2,16 +2,18 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fctiw(u32 *frD, void *frB)
 {
        FP_DECL_D(B);
+       FP_DECL_EX;
        unsigned int r;
 
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(B, frB);
        FP_TO_INT_D(r, B, 32, 1);
        frD[1] = r;
 
index 1514d59e146ea77bf103d37539da4c435bd4fcb8..71e782fd4fe35b13a2d1e1b77d6f8b7f32855738 100644 (file)
@@ -2,13 +2,15 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fctiwz(u32 *frD, void *frB)
 {
        FP_DECL_D(B);
+       FP_DECL_EX;
        u32 fpscr;
        unsigned int r;
 
@@ -16,7 +18,7 @@ fctiwz(u32 *frD, void *frB)
        __FPU_FPSCR &= ~(3);
        __FPU_FPSCR |= FP_RND_ZERO;
 
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(B, frB);
        FP_TO_INT_D(r, B, 32, 1);
        frD[1] = r;
 
index 18a20fe396b09f4d660ccb61ae2d6869fac15eeb..2db15097d98e9ba65ad049023561bdf397d26054 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fdiv(void *frD, void *frA, void *frB)
@@ -11,14 +12,15 @@ fdiv(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -49,5 +51,7 @@ fdiv(void *frD, void *frA, void *frB)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 24feed689c3581665796b6577eae5d9f988324a0..797f6a9a20b53f405687828c556ca526235ef201 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fdivs(void *frD, void *frA, void *frB)
@@ -12,14 +13,15 @@ fdivs(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -51,5 +53,7 @@ fdivs(void *frD, void *frA, void *frB)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index dedb465fdc68b5baa1fdc772286a37745fa2cc15..925313aa6f82b38b73307d0bfea6936d3021917e 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fmadd(void *frD, void *frA, void *frB, void *frC)
@@ -13,15 +14,16 @@ fmadd(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -44,5 +46,7 @@ fmadd(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 6bbb56d5502cb53c073fc3dea8e0f6ee0148bd1c..aea80ef79399d3630d5574a534a49e64d978810a 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fmadds(void *frD, void *frA, void *frB, void *frC)
@@ -14,15 +15,16 @@ fmadds(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -45,5 +47,7 @@ fmadds(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index f311e2c7e67e50fcc6a54f13a3534b68bf2f9ff9..a644d525fca66442f0c2322b52fe0d9c6d1d4f5c 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fmsub(void *frD, void *frA, void *frB, void *frC)
@@ -13,15 +14,16 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -47,5 +49,7 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 81a716d3ee2e6859c1ed7435dc8ca23cfed9368e..2fdeeb9bb569690b5c5e67adca34f2f3d51f68da 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fmsubs(void *frD, void *frA, void *frB, void *frC)
@@ -14,15 +15,16 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -48,5 +50,7 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 2f3d32784a04ac69e7fc5e8a13a97f0a163bbede..391fd17d3440fd85c1637480857ffc386c219e6c 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fmul(void *frD, void *frA, void *frB)
@@ -11,14 +12,15 @@ fmul(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
@@ -38,5 +40,7 @@ fmul(void *frD, void *frA, void *frB)
               R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 962b5883f784b0bb460f0f5448d4edcf737c42c9..2d3ec5f7da20f4c20a255e4eca8b804f2a47a913 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fmuls(void *frD, void *frA, void *frB)
@@ -12,14 +13,15 @@ fmuls(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
@@ -39,5 +41,7 @@ fmuls(void *frD, void *frA, void *frB)
               R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 8cf7827c4fb5949b142e9e7a5ab086bc7dd8cf01..2497b86494e5425ac64fe8355b91a0c2827afb4a 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fnmadd(void *frD, void *frA, void *frB, void *frC)
@@ -13,15 +14,16 @@ fnmadd(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -47,5 +49,7 @@ fnmadd(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index f1c4f0f0d807cf10db3e826b827a026d64a5b6a5..ee9d71e0b376f7578a9ebd25c0b8ef12746d4e72 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fnmadds(void *frD, void *frA, void *frB, void *frC)
@@ -14,15 +15,16 @@ fnmadds(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -48,5 +50,7 @@ fnmadds(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 98944e6e260181ca8c52ceaba4ebcb2df7ce2eff..3885a77acc9324919f89ee5aef1d6c842d4c1b17 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fnmsub(void *frD, void *frA, void *frB, void *frC)
@@ -13,15 +14,16 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -50,5 +52,7 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index b20f4eb63fb96ae7bd5fe156e4f41cd4fbe5a881..f835dfeb0fd1f3b8e8cdafec9d8cf581f6025b4b 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fnmsubs(void *frD, void *frA, void *frB, void *frC)
@@ -14,15 +15,16 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
        FP_DECL_D(B);
        FP_DECL_D(C);
        FP_DECL_D(T);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
-       __FP_UNPACK_D(C, frC);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
+       FP_UNPACK_DP(C, frC);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -51,5 +53,7 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 724ccbc0468e03332218be05b3f67093626e1cfb..ddcc14664b1a23a7116b95d9883cb92b4b7604ae 100644 (file)
@@ -2,24 +2,28 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 frsp(void *frD, void *frB)
 {
        FP_DECL_D(B);
+       FP_DECL_EX;
 
 #ifdef DEBUG
        printk("%s: D %p, B %p\n", __func__, frD, frB);
 #endif
 
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
 #endif
 
-       return __FP_PACK_DS(frD, B);
+       __FP_PACK_DS(frD, B);
+
+       return FP_CUR_EXCEPTIONS;
 }
index ecb5f28eb1f3f0f2701e8eac842202d216889362..1b0c144980320a87d5982d052419301ba15a2777 100644 (file)
@@ -2,19 +2,21 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fsel(u32 *frD, void *frA, u32 *frB, u32 *frC)
 {
        FP_DECL_D(A);
+       FP_DECL_EX;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC);
 #endif
 
-       __FP_UNPACK_D(A, frA);
+       FP_UNPACK_DP(A, frA);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
index 38ec2b752e9d1d65e7f7af874ee2c984e9d7caa7..3e90072693a0befdd1661000bfe629f1074ae9d0 100644 (file)
@@ -2,21 +2,23 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fsqrt(void *frD, void *frB)
 {
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frB);
 #endif
 
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
@@ -33,5 +35,7 @@ fsqrt(void *frD, void *frB)
        printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 335263e06ee54d56cbe2cd7d296e9a9695cff846..2843be986e2e97aa1a09f2ad8e5e7eb46cdd9852 100644 (file)
@@ -2,22 +2,24 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fsqrts(void *frD, void *frB)
 {
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p %p\n", __func__, frD, frB);
 #endif
 
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
@@ -34,5 +36,7 @@ fsqrts(void *frD, void *frB)
        printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 208d20fc52a51bb6656203e70b8e8ef38313c8e9..78b09446a0e14f61e5288aba797df5ca87c523de 100644 (file)
@@ -2,8 +2,9 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
 
 int
 fsub(void *frD, void *frA, void *frB)
@@ -11,14 +12,15 @@ fsub(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -37,5 +39,7 @@ fsub(void *frD, void *frA, void *frB)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_D(frD, R));
+       __FP_PACK_D(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 0e61b808c44b88df221e6ca16fb49d6e5c3827e6..d3bf90863cf29ba0abec9285c0c386785b4b20c6 100644 (file)
@@ -2,9 +2,10 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 fsubs(void *frD, void *frA, void *frB)
@@ -12,14 +13,15 @@ fsubs(void *frD, void *frA, void *frB)
        FP_DECL_D(A);
        FP_DECL_D(B);
        FP_DECL_D(R);
+       FP_DECL_EX;
        int ret = 0;
 
 #ifdef DEBUG
        printk("%s: %p %p %p\n", __func__, frD, frA, frB);
 #endif
 
-       __FP_UNPACK_D(A, frA);
-       __FP_UNPACK_D(B, frB);
+       FP_UNPACK_DP(A, frA);
+       FP_UNPACK_DP(B, frB);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -38,5 +40,7 @@ fsubs(void *frD, void *frA, void *frB)
        printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return (ret | __FP_PACK_DS(frD, R));
+       __FP_PACK_DS(frD, R);
+
+       return FP_CUR_EXCEPTIONS;
 }
index 6ec90b57c61a5c3a11d1e4d5735852138860dcd6..79ac76d596c31f30279bb678a600be120308d750 100644 (file)
@@ -2,8 +2,8 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "sfp-machine.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/double.h>
 
 int
 lfd(void *frD, void *ea)
index 6f18ebe3a7ff510ec6aa7a8edd72fbc474e179ab..434ed27be8dbaee074943bc80b6141c773d2ecf6 100644 (file)
@@ -2,15 +2,17 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 lfs(void *frD, void *ea)
 {
        FP_DECL_D(R);
        FP_DECL_S(A);
+       FP_DECL_EX;
        float f;
 
 #ifdef DEBUG
@@ -20,7 +22,7 @@ lfs(void *frD, void *ea)
        if (copy_from_user(&f, ea, sizeof(float)))
                return -EFAULT;
 
-       __FP_UNPACK_S(A, &f);
+       FP_UNPACK_S(A, f);
 
 #ifdef DEBUG
        printk("A: %ld %lu %ld (%ld) [%08lx]\n", A_s, A_f, A_e, A_c,
@@ -33,5 +35,12 @@ lfs(void *frD, void *ea)
        printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
 #endif
 
-       return __FP_PACK_D(frD, R);
+       if (R_c == FP_CLS_NAN) {
+               R_e = _FP_EXPMAX_D;
+               _FP_PACK_RAW_2_P(D, frD, R);
+       } else {
+               __FP_PACK_D(frD, R);
+       }
+
+       return 0;
 }
index 29e545e0272e62abd85ec7cf3d4933b882ce6da8..164d55935bd82ce7903d0e6717ad2cc029d422bf 100644 (file)
@@ -8,8 +8,8 @@
 #include <asm/uaccess.h>
 #include <asm/reg.h>
 
-#include "sfp-machine.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/double.h>
 
 #define FLOATFUNC(x)   extern int x(void *, void *, void *, void *)
 
@@ -168,6 +168,8 @@ record_exception(struct pt_regs *regs, int eflag)
                        fpscr |= FPSCR_ZX;
                if (eflag & EFLAG_INEXACT)
                        fpscr |= FPSCR_XX;
+               if (eflag & EFLAG_INVALID)
+                       fpscr |= FPSCR_VX;
                if (eflag & EFLAG_VXSNAN)
                        fpscr |= FPSCR_VXSNAN;
                if (eflag & EFLAG_VXISI)
@@ -188,7 +190,7 @@ record_exception(struct pt_regs *regs, int eflag)
                        fpscr |= FPSCR_VXCVI;
        }
 
-       fpscr &= ~(FPSCR_VX);
+//     fpscr &= ~(FPSCR_VX);
        if (fpscr & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI |
                     FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
                     FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI))
index 41ba247faf897e1d35dad1728c144b89f7e18573..e948d5708e2b722041c712810964bb95fa0f197e 100644 (file)
@@ -2,7 +2,8 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
 
 int
 mcrfs(u32 *ccr, u32 crfD, u32 crfS)
index b0e2106e6eb6d71e10a8bf678b8f97e72248b274..5526cf96ede5e0e33b462f09f44b8c8177c636c9 100644 (file)
@@ -2,7 +2,8 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
 
 int
 mffs(u32 *frD)
index d3062350ea215535cf60d999ff181e95197be6ed..bc985585bca8afd65c6b964184a30e74b4376ede 100644 (file)
@@ -2,7 +2,8 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
 
 int
 mtfsb0(int crbD)
index 2e948704b56ea0259aa00ba8b6619d97f923c545..fe6ed5ac85b331cf75e14c695996a6733ff03a14 100644 (file)
@@ -2,7 +2,8 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
 
 int
 mtfsb1(int crbD)
index 48014d8e3af1efa9e7c701c59140ec75f658180f..dbce92e4f046d9295c057f4fb3408f52b17990cc 100644 (file)
@@ -2,12 +2,14 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
 
 int
 mtfsf(unsigned int FM, u32 *frB)
 {
        u32 mask;
+       u32 fpscr;
 
        if (FM == 0)
                return 0;
@@ -37,6 +39,22 @@ mtfsf(unsigned int FM, u32 *frB)
        __FPU_FPSCR &= ~(mask);
        __FPU_FPSCR |= (frB[1] & mask);
 
+       __FPU_FPSCR &= ~(FPSCR_VX);
+       if (__FPU_FPSCR & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI |
+                    FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
+                    FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI))
+               __FPU_FPSCR |= FPSCR_VX;
+
+       fpscr = __FPU_FPSCR;
+       fpscr &= ~(FPSCR_FEX);
+       if (((fpscr & FPSCR_VX) && (fpscr & FPSCR_VE)) ||
+           ((fpscr & FPSCR_OX) && (fpscr & FPSCR_OE)) ||
+           ((fpscr & FPSCR_UX) && (fpscr & FPSCR_UE)) ||
+           ((fpscr & FPSCR_ZX) && (fpscr & FPSCR_ZE)) ||
+           ((fpscr & FPSCR_XX) && (fpscr & FPSCR_XE)))
+               fpscr |= FPSCR_FEX;
+       __FPU_FPSCR = fpscr;
+
 #ifdef DEBUG
        printk("%s: %02x %p: %08lx\n", __func__, FM, frB, __FPU_FPSCR);
 #endif
index 031e200935493c49be352a410127a57476853faf..fd2acc26813b7f1a240f80427075bc43a52b0c53 100644 (file)
@@ -2,7 +2,8 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
 
 int
 mtfsfi(unsigned int crfD, unsigned int IMM)
diff --git a/arch/powerpc/math-emu/op-1.h b/arch/powerpc/math-emu/op-1.h
deleted file mode 100644 (file)
index c92fa95..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Basic one-word fraction declaration and manipulation.
- */
-
-#define _FP_FRAC_DECL_1(X)     _FP_W_TYPE X##_f
-#define _FP_FRAC_COPY_1(D,S)   (D##_f = S##_f)
-#define _FP_FRAC_SET_1(X,I)    (X##_f = I)
-#define _FP_FRAC_HIGH_1(X)     (X##_f)
-#define _FP_FRAC_LOW_1(X)      (X##_f)
-#define _FP_FRAC_WORD_1(X,w)   (X##_f)
-
-#define _FP_FRAC_ADDI_1(X,I)   (X##_f += I)
-#define _FP_FRAC_SLL_1(X,N)                    \
-  do {                                         \
-    if (__builtin_constant_p(N) && (N) == 1)   \
-      X##_f += X##_f;                          \
-    else                                       \
-      X##_f <<= (N);                           \
-  } while (0)
-#define _FP_FRAC_SRL_1(X,N)    (X##_f >>= N)
-
-/* Right shift with sticky-lsb.  */
-#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
-
-#define __FP_FRAC_SRS_1(X,N,sz)                                                \
-   (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1               \
-                    ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
-
-#define _FP_FRAC_ADD_1(R,X,Y)  (R##_f = X##_f + Y##_f)
-#define _FP_FRAC_SUB_1(R,X,Y)  (R##_f = X##_f - Y##_f)
-#define _FP_FRAC_CLZ_1(z, X)   __FP_CLZ(z, X##_f)
-
-/* Predicates */
-#define _FP_FRAC_NEGP_1(X)     ((_FP_WS_TYPE)X##_f < 0)
-#define _FP_FRAC_ZEROP_1(X)    (X##_f == 0)
-#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs)
-#define _FP_FRAC_EQ_1(X, Y)    (X##_f == Y##_f)
-#define _FP_FRAC_GE_1(X, Y)    (X##_f >= Y##_f)
-#define _FP_FRAC_GT_1(X, Y)    (X##_f > Y##_f)
-
-#define _FP_ZEROFRAC_1         0
-#define _FP_MINFRAC_1          1
-
-/*
- * Unpack the raw bits of a native fp value.  Do not classify or
- * normalize the data.
- */
-
-#define _FP_UNPACK_RAW_1(fs, X, val)                           \
-  do {                                                         \
-    union _FP_UNION_##fs _flo; _flo.flt = (val);               \
-                                                               \
-    X##_f = _flo.bits.frac;                                    \
-    X##_e = _flo.bits.exp;                                     \
-    X##_s = _flo.bits.sign;                                    \
-  } while (0)
-
-
-/*
- * Repack the raw bits of a native fp value.
- */
-
-#define _FP_PACK_RAW_1(fs, val, X)                             \
-  do {                                                         \
-    union _FP_UNION_##fs _flo;                                 \
-                                                               \
-    _flo.bits.frac = X##_f;                                    \
-    _flo.bits.exp  = X##_e;                                    \
-    _flo.bits.sign = X##_s;                                    \
-                                                               \
-    (val) = _flo.flt;                                          \
-  } while (0)
-
-
-/*
- * Multiplication algorithms:
- */
-
-/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
-   multiplication immediately.  */
-
-#define _FP_MUL_MEAT_1_imm(fs, R, X, Y)                                        \
-  do {                                                                 \
-    R##_f = X##_f * Y##_f;                                             \
-    /* Normalize since we know where the msb of the multiplicands      \
-       were (bit B), we know that the msb of the of the product is     \
-       at either 2B or 2B-1.  */                                       \
-    _FP_FRAC_SRS_1(R, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);     \
-  } while (0)
-
-/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
-
-#define _FP_MUL_MEAT_1_wide(fs, R, X, Y, doit)                         \
-  do {                                                                 \
-    _FP_W_TYPE _Z_f0, _Z_f1;                                           \
-    doit(_Z_f1, _Z_f0, X##_f, Y##_f);                                  \
-    /* Normalize since we know where the msb of the multiplicands      \
-       were (bit B), we know that the msb of the of the product is     \
-       at either 2B or 2B-1.  */                                       \
-    _FP_FRAC_SRS_2(_Z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);    \
-    R##_f = _Z_f0;                                                     \
-  } while (0)
-
-/* Finally, a simple widening multiply algorithm.  What fun!  */
-
-#define _FP_MUL_MEAT_1_hard(fs, R, X, Y)                               \
-  do {                                                                 \
-    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;         \
-                                                                       \
-    /* split the words in half */                                      \
-    _xh = X##_f >> (_FP_W_TYPE_SIZE/2);                                        \
-    _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);                \
-    _yh = Y##_f >> (_FP_W_TYPE_SIZE/2);                                        \
-    _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);                \
-                                                                       \
-    /* multiply the pieces */                                          \
-    _z_f0 = _xl * _yl;                                                 \
-    _a_f0 = _xh * _yl;                                                 \
-    _a_f1 = _xl * _yh;                                                 \
-    _z_f1 = _xh * _yh;                                                 \
-                                                                       \
-    /* reassemble into two full words */                               \
-    if ((_a_f0 += _a_f1) < _a_f1)                                      \
-      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);                   \
-    _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);                              \
-    _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);                              \
-    _FP_FRAC_ADD_2(_z, _z, _a);                                                \
-                                                                       \
-    /* normalize */                                                    \
-    _FP_FRAC_SRS_2(_z, _FP_WFRACBITS_##fs - 1, 2*_FP_WFRACBITS_##fs);  \
-    R##_f = _z_f0;                                                     \
-  } while (0)
-
-
-/*
- * Division algorithms:
- */
-
-/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
-   division immediately.  Give this macro either _FP_DIV_HELP_imm for
-   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
-   choose will depend on what the compiler does with divrem4.  */
-
-#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)          \
-  do {                                                 \
-    _FP_W_TYPE _q, _r;                                 \
-    X##_f <<= (X##_f < Y##_f                           \
-              ? R##_e--, _FP_WFRACBITS_##fs            \
-              : _FP_WFRACBITS_##fs - 1);               \
-    doit(_q, _r, X##_f, Y##_f);                                \
-    R##_f = _q | (_r != 0);                            \
-  } while (0)
-
-/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
-   that may be useful in this situation.  This first is for a primitive
-   that requires normalization, the second for one that does not.  Look
-   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
-
-#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)                          \
-  do {                                                                 \
-    _FP_W_TYPE _nh, _nl, _q, _r;                                       \
-                                                                       \
-    /* Normalize Y -- i.e. make the most significant bit set.  */      \
-    Y##_f <<= _FP_WFRACXBITS_##fs - 1;                                 \
-                                                                       \
-    /* Shift X op correspondingly high, that is, up one full word.  */ \
-    if (X##_f <= Y##_f)                                                        \
-      {                                                                        \
-       _nl = 0;                                                        \
-       _nh = X##_f;                                                    \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       R##_e++;                                                        \
-       _nl = X##_f << (_FP_W_TYPE_SIZE-1);                             \
-       _nh = X##_f >> 1;                                               \
-      }                                                                        \
-                                                                       \
-    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);                               \
-    R##_f = _q | (_r != 0);                                            \
-  } while (0)
-
-#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)               \
-  do {                                                 \
-    _FP_W_TYPE _nh, _nl, _q, _r;                       \
-    if (X##_f < Y##_f)                                 \
-      {                                                        \
-       R##_e--;                                        \
-       _nl = X##_f << _FP_WFRACBITS_##fs;              \
-       _nh = X##_f >> _FP_WFRACXBITS_##fs;             \
-      }                                                        \
-    else                                               \
-      {                                                        \
-       _nl = X##_f << (_FP_WFRACBITS_##fs - 1);        \
-       _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);       \
-      }                                                        \
-    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);               \
-    R##_f = _q | (_r != 0);                            \
-  } while (0)
-
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- */
-
-#define _FP_SQRT_MEAT_1(R, S, T, X, q)                 \
-  do {                                                 \
-    while (q)                                          \
-      {                                                        \
-        T##_f = S##_f + q;                             \
-        if (T##_f <= X##_f)                            \
-          {                                            \
-            S##_f = T##_f + q;                         \
-            X##_f -= T##_f;                            \
-            R##_f += q;                                        \
-          }                                            \
-        _FP_FRAC_SLL_1(X, 1);                          \
-        q >>= 1;                                       \
-      }                                                        \
-  } while (0)
-
-/*
- * Assembly/disassembly for converting to/from integral types.
- * No shifting or overflow handled here.
- */
-
-#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)       (r = X##_f)
-#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)    (X##_f = r)
-
-
-/*
- * Convert FP values between word sizes
- */
-
-#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S)                              \
-  do {                                                                 \
-    D##_f = S##_f;                                                     \
-    if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs)                     \
-      _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs),     \
-                    _FP_WFRACBITS_##sfs);                              \
-    else                                                               \
-      D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs;             \
-  } while (0)
diff --git a/arch/powerpc/math-emu/op-2.h b/arch/powerpc/math-emu/op-2.h
deleted file mode 100644 (file)
index 7d6f17c..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Basic two-word fraction declaration and manipulation.
- */
-
-#define _FP_FRAC_DECL_2(X)     _FP_W_TYPE X##_f0, X##_f1
-#define _FP_FRAC_COPY_2(D,S)   (D##_f0 = S##_f0, D##_f1 = S##_f1)
-#define _FP_FRAC_SET_2(X,I)    __FP_FRAC_SET_2(X, I)
-#define _FP_FRAC_HIGH_2(X)     (X##_f1)
-#define _FP_FRAC_LOW_2(X)      (X##_f0)
-#define _FP_FRAC_WORD_2(X,w)   (X##_f##w)
-
-#define _FP_FRAC_SLL_2(X,N)                                            \
-  do {                                                                 \
-    if ((N) < _FP_W_TYPE_SIZE)                                         \
-      {                                                                        \
-        if (__builtin_constant_p(N) && (N) == 1)                       \
-          {                                                            \
-            X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0);  \
-            X##_f0 += X##_f0;                                          \
-          }                                                            \
-        else                                                           \
-          {                                                            \
-           X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
-           X##_f0 <<= (N);                                             \
-         }                                                             \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE);                     \
-       X##_f0 = 0;                                                     \
-      }                                                                        \
-  } while (0)
-
-#define _FP_FRAC_SRL_2(X,N)                                            \
-  do {                                                                 \
-    if ((N) < _FP_W_TYPE_SIZE)                                         \
-      {                                                                        \
-       X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N));     \
-       X##_f1 >>= (N);                                                 \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE);                     \
-       X##_f1 = 0;                                                     \
-      }                                                                        \
-  } while (0)
-
-/* Right shift with sticky-lsb.  */
-#define _FP_FRAC_SRS_2(X,N,sz)                                         \
-  do {                                                                 \
-    if ((N) < _FP_W_TYPE_SIZE)                                         \
-      {                                                                        \
-       X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) |   \
-                 (__builtin_constant_p(N) && (N) == 1                  \
-                  ? X##_f0 & 1                                         \
-                  : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0));        \
-       X##_f1 >>= (N);                                                 \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) |                   \
-                 (((X##_f1 << (2 * _FP_W_TYPE_SIZE - (N))) |           \
-                  X##_f0) != 0));                                      \
-       X##_f1 = 0;                                                     \
-      }                                                                        \
-  } while (0)
-
-#define _FP_FRAC_ADDI_2(X,I) \
-  __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
-
-#define _FP_FRAC_ADD_2(R,X,Y) \
-  __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
-
-#define _FP_FRAC_SUB_2(R,X,Y) \
-  __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
-
-#define _FP_FRAC_CLZ_2(R,X)    \
-  do {                         \
-    if (X##_f1)                        \
-      __FP_CLZ(R,X##_f1);      \
-    else                       \
-    {                          \
-      __FP_CLZ(R,X##_f0);      \
-      R += _FP_W_TYPE_SIZE;    \
-    }                          \
-  } while(0)
-
-/* Predicates */
-#define _FP_FRAC_NEGP_2(X)     ((_FP_WS_TYPE)X##_f1 < 0)
-#define _FP_FRAC_ZEROP_2(X)    ((X##_f1 | X##_f0) == 0)
-#define _FP_FRAC_OVERP_2(fs,X) (X##_f1 & _FP_OVERFLOW_##fs)
-#define _FP_FRAC_EQ_2(X, Y)    (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
-#define _FP_FRAC_GT_2(X, Y)    \
-  ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
-#define _FP_FRAC_GE_2(X, Y)    \
-  ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
-
-#define _FP_ZEROFRAC_2         0, 0
-#define _FP_MINFRAC_2          0, 1
-
-/*
- * Internals
- */
-
-#define __FP_FRAC_SET_2(X,I1,I0)       (X##_f0 = I0, X##_f1 = I1)
-
-#define __FP_CLZ_2(R, xh, xl)  \
-  do {                         \
-    if (xh)                    \
-      __FP_CLZ(R,xl);          \
-    else                       \
-    {                          \
-      __FP_CLZ(R,xl);          \
-      R += _FP_W_TYPE_SIZE;    \
-    }                          \
-  } while(0)
-
-#if 0
-
-#ifndef __FP_FRAC_ADDI_2
-#define __FP_FRAC_ADDI_2(xh, xl, i) \
-  (xh += ((xl += i) < i))
-#endif
-#ifndef __FP_FRAC_ADD_2
-#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
-  (rh = xh + yh + ((rl = xl + yl) < xl))
-#endif
-#ifndef __FP_FRAC_SUB_2
-#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
-  (rh = xh - yh - ((rl = xl - yl) > xl))
-#endif
-
-#else
-
-#undef __FP_FRAC_ADDI_2
-#define __FP_FRAC_ADDI_2(xh, xl, i)    add_ssaaaa(xh, xl, xh, xl, 0, i)
-#undef __FP_FRAC_ADD_2
-#define __FP_FRAC_ADD_2                        add_ssaaaa
-#undef __FP_FRAC_SUB_2
-#define __FP_FRAC_SUB_2                        sub_ddmmss
-
-#endif
-
-/*
- * Unpack the raw bits of a native fp value.  Do not classify or
- * normalize the data.
- */
-
-#define _FP_UNPACK_RAW_2(fs, X, val)                   \
-  do {                                                 \
-    union _FP_UNION_##fs _flo; _flo.flt = (val);       \
-                                                       \
-    X##_f0 = _flo.bits.frac0;                          \
-    X##_f1 = _flo.bits.frac1;                          \
-    X##_e  = _flo.bits.exp;                            \
-    X##_s  = _flo.bits.sign;                           \
-  } while (0)
-
-
-/*
- * Repack the raw bits of a native fp value.
- */
-
-#define _FP_PACK_RAW_2(fs, val, X)                     \
-  do {                                                 \
-    union _FP_UNION_##fs _flo;                         \
-                                                       \
-    _flo.bits.frac0 = X##_f0;                          \
-    _flo.bits.frac1 = X##_f1;                          \
-    _flo.bits.exp   = X##_e;                           \
-    _flo.bits.sign  = X##_s;                           \
-                                                       \
-    (val) = _flo.flt;                                  \
-  } while (0)
-
-
-/*
- * Multiplication algorithms:
- */
-
-/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
-
-#define _FP_MUL_MEAT_2_wide(fs, R, X, Y, doit)                         \
-  do {                                                                 \
-    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);     \
-                                                                       \
-    doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
-    doit(_b_f1, _b_f0, X##_f0, Y##_f1);                                        \
-    doit(_c_f1, _c_f0, X##_f1, Y##_f0);                                        \
-    doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
-                                                                       \
-    __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
-                   _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0),        \
-                   0, _b_f1, _b_f0, 0,                                 \
-                   _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),        \
-                   _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0));       \
-    __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
-                   _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0),        \
-                   0, _c_f1, _c_f0, 0,                                 \
-                   _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),        \
-                   _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0));       \
-                                                                       \
-    /* Normalize since we know where the msb of the multiplicands      \
-       were (bit B), we know that the msb of the of the product is     \
-       at either 2B or 2B-1.  */                                       \
-    _FP_FRAC_SRS_4(_z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs);    \
-    R##_f0 = _FP_FRAC_WORD_4(_z,0);                                    \
-    R##_f1 = _FP_FRAC_WORD_4(_z,1);                                    \
-  } while (0)
-
-/* This next macro appears to be totally broken. Fortunately nowhere
- * seems to use it :-> The problem is that we define _z[4] but
- * then use it in _FP_FRAC_SRS_4, which will attempt to access
- * _z_f[n] which will cause an error. The fix probably involves
- * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998
- */
-#define _FP_MUL_MEAT_2_gmp(fs, R, X, Y)                                        \
-  do {                                                                 \
-    _FP_W_TYPE _x[2], _y[2], _z[4];                                    \
-    _x[0] = X##_f0; _x[1] = X##_f1;                                    \
-    _y[0] = Y##_f0; _y[1] = Y##_f1;                                    \
-                                                                       \
-    mpn_mul_n(_z, _x, _y, 2);                                          \
-                                                                       \
-    /* Normalize since we know where the msb of the multiplicands      \
-       were (bit B), we know that the msb of the of the product is     \
-       at either 2B or 2B-1.  */                                       \
-    _FP_FRAC_SRS_4(_z, _FP_WFRACBITS##_fs-1, 2*_FP_WFRACBITS_##fs);    \
-    R##_f0 = _z[0];                                                    \
-    R##_f1 = _z[1];                                                    \
-  } while (0)
-
-
-/*
- * Division algorithms:
- * This seems to be giving me difficulties -- PMM
- * Look, NetBSD seems to be able to comment algorithms. Can't you?
- * I've thrown printks at the problem.
- * This now appears to work, but I still don't really know why.
- * Also, I don't think the result is properly normalised...
- */
-
-#define _FP_DIV_MEAT_2_udiv_64(fs, R, X, Y)                            \
-  do {                                                                 \
-    extern void _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],       \
-                              _FP_W_TYPE n1, _FP_W_TYPE n0,            \
-                              _FP_W_TYPE d1, _FP_W_TYPE d0);           \
-    _FP_W_TYPE _n_f3, _n_f2, _n_f1, _n_f0, _r_f1, _r_f0;               \
-    _FP_W_TYPE _q_f1, _q_f0, _m_f1, _m_f0;                             \
-    _FP_W_TYPE _rmem[2], _qmem[2];                                     \
-    /* I think this check is to ensure that the result is normalised.   \
-     * Assuming X,Y normalised (ie in [1.0,2.0)) X/Y will be in         \
-     * [0.5,2.0). Furthermore, it will be less than 1.0 iff X < Y.      \
-     * In this case we tweak things. (this is based on comments in      \
-     * the NetBSD FPU emulation code. )                                 \
-     * We know X,Y are normalised because we ensure this as part of     \
-     * the unpacking process. -- PMM                                    \
-     */                                                                        \
-    if (_FP_FRAC_GT_2(X, Y))                                           \
-      {                                                                        \
-/*     R##_e++; */                                                     \
-       _n_f3 = X##_f1 >> 1;                                            \
-       _n_f2 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1;          \
-       _n_f1 = X##_f0 << (_FP_W_TYPE_SIZE - 1);                        \
-       _n_f0 = 0;                                                      \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       R##_e--;                                                        \
-       _n_f3 = X##_f1;                                                 \
-       _n_f2 = X##_f0;                                                 \
-       _n_f1 = _n_f0 = 0;                                              \
-      }                                                                        \
-                                                                       \
-    /* Normalize, i.e. make the most significant bit of the            \
-       denominator set.  CHANGED: - 1 to nothing -- PMM */             \
-    _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs /* -1 */);                   \
-                                                                       \
-    /* Do the 256/128 bit division given the 128-bit _fp_udivmodtf4    \
-       primitive snagged from libgcc2.c.  */                           \
-                                                                       \
-    _fp_udivmodti4(_qmem, _rmem, _n_f3, _n_f2, 0, Y##_f1);             \
-    _q_f1 = _qmem[0];                                                  \
-    umul_ppmm(_m_f1, _m_f0, _q_f1, Y##_f0);                            \
-    _r_f1 = _rmem[0];                                                  \
-    _r_f0 = _n_f1;                                                     \
-    if (_FP_FRAC_GT_2(_m, _r))                                         \
-      {                                                                        \
-       _q_f1--;                                                        \
-       _FP_FRAC_ADD_2(_r, _r, Y);                                      \
-       if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))              \
-         {                                                             \
-           _q_f1--;                                                    \
-           _FP_FRAC_ADD_2(_r, _r, Y);                                  \
-         }                                                             \
-      }                                                                        \
-    _FP_FRAC_SUB_2(_r, _r, _m);                                                \
-                                                                       \
-    _fp_udivmodti4(_qmem, _rmem, _r_f1, _r_f0, 0, Y##_f1);             \
-    _q_f0 = _qmem[0];                                                  \
-    umul_ppmm(_m_f1, _m_f0, _q_f0, Y##_f0);                            \
-    _r_f1 = _rmem[0];                                                  \
-    _r_f0 = _n_f0;                                                     \
-    if (_FP_FRAC_GT_2(_m, _r))                                         \
-      {                                                                        \
-       _q_f0--;                                                        \
-       _FP_FRAC_ADD_2(_r, _r, Y);                                      \
-       if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))              \
-         {                                                             \
-           _q_f0--;                                                    \
-           _FP_FRAC_ADD_2(_r, _r, Y);                                  \
-         }                                                             \
-      }                                                                        \
-    _FP_FRAC_SUB_2(_r, _r, _m);                                                \
-                                                                       \
-    R##_f1 = _q_f1;                                                    \
-    R##_f0 = _q_f0 | ((_r_f1 | _r_f0) != 0);                           \
-    /* adjust so answer is normalized again. I'm not sure what the     \
-     * final sz param should be. In practice it's never used since      \
-     * N is 1 which is always going to be < _FP_W_TYPE_SIZE...         \
-     */                                                                        \
-    /* _FP_FRAC_SRS_2(R,1,_FP_WFRACBITS_##fs); */                      \
-  } while (0)
-
-
-#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y)                                        \
-  do {                                                                 \
-    _FP_W_TYPE _x[4], _y[2], _z[4];                                    \
-    _y[0] = Y##_f0; _y[1] = Y##_f1;                                    \
-    _x[0] = _x[3] = 0;                                                 \
-    if (_FP_FRAC_GT_2(X, Y))                                           \
-      {                                                                        \
-       R##_e++;                                                        \
-       _x[1] = (X##_f0 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE) |        \
-                X##_f1 >> (_FP_W_TYPE_SIZE -                           \
-                           (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE)));      \
-       _x[2] = X##_f1 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE);          \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       _x[1] = (X##_f0 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE) |          \
-                X##_f1 >> (_FP_W_TYPE_SIZE -                           \
-                           (_FP_WFRACBITS - _FP_W_TYPE_SIZE)));        \
-       _x[2] = X##_f1 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE);            \
-      }                                                                        \
-                                                                       \
-    (void) mpn_divrem (_z, 0, _x, 4, _y, 2);                           \
-    R##_f1 = _z[1];                                                    \
-    R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0);                           \
-  } while (0)
-
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- */
-
-#define _FP_SQRT_MEAT_2(R, S, T, X, q)                 \
-  do {                                                 \
-    while (q)                                          \
-      {                                                        \
-        T##_f1 = S##_f1 + q;                           \
-        if (T##_f1 <= X##_f1)                          \
-          {                                            \
-            S##_f1 = T##_f1 + q;                       \
-            X##_f1 -= T##_f1;                          \
-            R##_f1 += q;                               \
-          }                                            \
-        _FP_FRAC_SLL_2(X, 1);                          \
-        q >>= 1;                                       \
-      }                                                        \
-    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                \
-    while (q)                                          \
-      {                                                        \
-        T##_f0 = S##_f0 + q;                           \
-        T##_f1 = S##_f1;                               \
-        if (T##_f1 < X##_f1 ||                                 \
-            (T##_f1 == X##_f1 && T##_f0 < X##_f0))     \
-          {                                            \
-            S##_f0 = T##_f0 + q;                       \
-            if (((_FP_WS_TYPE)T##_f0) < 0 &&           \
-                ((_FP_WS_TYPE)S##_f0) >= 0)            \
-              S##_f1++;                                        \
-            _FP_FRAC_SUB_2(X, X, T);                   \
-            R##_f0 += q;                               \
-          }                                            \
-        _FP_FRAC_SLL_2(X, 1);                          \
-        q >>= 1;                                       \
-      }                                                        \
-  } while (0)
-
-
-/*
- * Assembly/disassembly for converting to/from integral types.
- * No shifting or overflow handled here.
- */
-
-#define _FP_FRAC_ASSEMBLE_2(r, X, rsize)       \
-  do {                                         \
-    if (rsize <= _FP_W_TYPE_SIZE)              \
-      r = X##_f0;                              \
-    else                                       \
-      {                                                \
-       r = X##_f1;                             \
-       r <<= _FP_W_TYPE_SIZE;                  \
-       r += X##_f0;                            \
-      }                                                \
-  } while (0)
-
-#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize)                            \
-  do {                                                                 \
-    X##_f0 = r;                                                                \
-    X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);    \
-  } while (0)
-
-/*
- * Convert FP values between word sizes
- */
-
-#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S)                              \
-  do {                                                                 \
-    _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
-                  _FP_WFRACBITS_##sfs);                                \
-    D##_f = S##_f0;                                                    \
-  } while (0)
-
-#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S)                              \
-  do {                                                                 \
-    D##_f0 = S##_f;                                                    \
-    D##_f1 = 0;                                                                \
-    _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
-  } while (0)
-
diff --git a/arch/powerpc/math-emu/op-4.h b/arch/powerpc/math-emu/op-4.h
deleted file mode 100644 (file)
index c9ae626..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Basic four-word fraction declaration and manipulation.
- *
- * When adding quadword support for 32 bit machines, we need
- * to be a little careful as double multiply uses some of these
- * macros: (in op-2.h)
- * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4,
- * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4
- * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use
- * _FP_FRAC_DECL_4: it appears to be broken and is not used
- * anywhere anyway. )
- *
- * I've now fixed all the macros that were here from the sparc64 code.
- * [*none* of the shift macros were correct!] -- PMM 02/1998
- *
- * The only quadword stuff that remains to be coded is:
- * 1) the conversion to/from ints, which requires
- * that we check (in op-common.h) that the following do the right thing
- * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt)
- * 2) multiply, divide and sqrt, which require:
- * _FP_MUL_MEAT_4_*(R,X,Y), _FP_DIV_MEAT_4_*(R,X,Y), _FP_SQRT_MEAT_4(R,S,T,X,q),
- * This also needs _FP_MUL_MEAT_Q and _FP_DIV_MEAT_Q to be defined to
- * some suitable _FP_MUL_MEAT_4_* macros in sfp-machine.h.
- * [we're free to choose whatever FP_MUL_MEAT_4_* macros we need for
- * these; they are used nowhere else. ]
- */
-
-#define _FP_FRAC_DECL_4(X)     _FP_W_TYPE X##_f[4]
-#define _FP_FRAC_COPY_4(D,S)                   \
-  (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1],   \
-   D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
-/* The _FP_FRAC_SET_n(X,I) macro is intended for use with another
- * macro such as _FP_ZEROFRAC_n which returns n comma separated values.
- * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3)
- * which just assigns the In values to the array X##_f[].
- * This is why the number of parameters doesn't appear to match
- * at first glance...      -- PMM
- */
-#define _FP_FRAC_SET_4(X,I)    __FP_FRAC_SET_4(X, I)
-#define _FP_FRAC_HIGH_4(X)     (X##_f[3])
-#define _FP_FRAC_LOW_4(X)      (X##_f[0])
-#define _FP_FRAC_WORD_4(X,w)   (X##_f[w])
-
-#define _FP_FRAC_SLL_4(X,N)                                            \
-  do {                                                                 \
-    _FP_I_TYPE _up, _down, _skip, _i;                                  \
-    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
-    _up = (N) % _FP_W_TYPE_SIZE;                                       \
-    _down = _FP_W_TYPE_SIZE - _up;                                     \
-    for (_i = 3; _i > _skip; --_i)                                     \
-      X##_f[_i] = X##_f[_i-_skip] << _up | X##_f[_i-_skip-1] >> _down; \
-/* bugfixed: was X##_f[_i] <<= _up;  -- PMM 02/1998 */                  \
-    X##_f[_i] = X##_f[0] << _up;                                       \
-    for (--_i; _i >= 0; --_i)                                          \
-      X##_f[_i] = 0;                                                   \
-  } while (0)
-
-/* This one was broken too */
-#define _FP_FRAC_SRL_4(X,N)                                            \
-  do {                                                                 \
-    _FP_I_TYPE _up, _down, _skip, _i;                                  \
-    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
-    _down = (N) % _FP_W_TYPE_SIZE;                                     \
-    _up = _FP_W_TYPE_SIZE - _down;                                     \
-    for (_i = 0; _i < 3-_skip; ++_i)                                   \
-      X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \
-    X##_f[_i] = X##_f[3] >> _down;                                     \
-    for (++_i; _i < 4; ++_i)                                           \
-      X##_f[_i] = 0;                                                   \
-  } while (0)
-
-
-/* Right shift with sticky-lsb.
- * What this actually means is that we do a standard right-shift,
- * but that if any of the bits that fall off the right hand side
- * were one then we always set the LSbit.
- */
-#define _FP_FRAC_SRS_4(X,N,size)                                       \
-  do {                                                                 \
-    _FP_I_TYPE _up, _down, _skip, _i;                                  \
-    _FP_W_TYPE _s;                                                     \
-    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
-    _down = (N) % _FP_W_TYPE_SIZE;                                     \
-    _up = _FP_W_TYPE_SIZE - _down;                                     \
-    for (_s = _i = 0; _i < _skip; ++_i)                                        \
-      _s |= X##_f[_i];                                                 \
-    _s |= X##_f[_i] << _up;                                            \
-/* s is now != 0 if we want to set the LSbit */                         \
-    for (_i = 0; _i < 3-_skip; ++_i)                                   \
-      X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \
-    X##_f[_i] = X##_f[3] >> _down;                                     \
-    for (++_i; _i < 4; ++_i)                                           \
-      X##_f[_i] = 0;                                                   \
-    /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
-    X##_f[0] |= (_s != 0);                                              \
-  } while (0)
-
-#define _FP_FRAC_ADD_4(R,X,Y)                                          \
-  __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],              \
-                 X##_f[3], X##_f[2], X##_f[1], X##_f[0],               \
-                 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
-
-#define _FP_FRAC_SUB_4(R,X,Y)                                           \
-  __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],              \
-                 X##_f[3], X##_f[2], X##_f[1], X##_f[0],               \
-                 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
-
-#define _FP_FRAC_ADDI_4(X,I)                                            \
-  __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
-
-#define _FP_ZEROFRAC_4  0,0,0,0
-#define _FP_MINFRAC_4   0,0,0,1
-
-#define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
-#define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
-#define _FP_FRAC_OVERP_4(fs,X)  (X##_f[0] & _FP_OVERFLOW_##fs)
-
-#define _FP_FRAC_EQ_4(X,Y)                              \
- (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]          \
-  && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
-
-#define _FP_FRAC_GT_4(X,Y)                              \
- (X##_f[3] > Y##_f[3] ||                                \
-  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||      \
-   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||     \
-    (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0])       \
-   ))                                                   \
-  ))                                                    \
- )
-
-#define _FP_FRAC_GE_4(X,Y)                              \
- (X##_f[3] > Y##_f[3] ||                                \
-  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||      \
-   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||     \
-    (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0])      \
-   ))                                                   \
-  ))                                                    \
- )
-
-
-#define _FP_FRAC_CLZ_4(R,X)             \
-  do {                                  \
-    if (X##_f[3])                       \
-    {                                   \
-        __FP_CLZ(R,X##_f[3]);           \
-    }                                   \
-    else if (X##_f[2])                  \
-    {                                   \
-        __FP_CLZ(R,X##_f[2]);           \
-        R += _FP_W_TYPE_SIZE;           \
-    }                                   \
-    else if (X##_f[1])                  \
-    {                                   \
-        __FP_CLZ(R,X##_f[2]);           \
-        R += _FP_W_TYPE_SIZE*2;         \
-    }                                   \
-    else                                \
-    {                                   \
-        __FP_CLZ(R,X##_f[0]);           \
-        R += _FP_W_TYPE_SIZE*3;         \
-    }                                   \
-  } while(0)
-
-
-#define _FP_UNPACK_RAW_4(fs, X, val)                            \
-  do {                                                          \
-    union _FP_UNION_##fs _flo; _flo.flt = (val);               \
-    X##_f[0] = _flo.bits.frac0;                                 \
-    X##_f[1] = _flo.bits.frac1;                                 \
-    X##_f[2] = _flo.bits.frac2;                                 \
-    X##_f[3] = _flo.bits.frac3;                                 \
-    X##_e  = _flo.bits.exp;                                     \
-    X##_s  = _flo.bits.sign;                                    \
-  } while (0)
-
-#define _FP_PACK_RAW_4(fs, val, X)                              \
-  do {                                                          \
-    union _FP_UNION_##fs _flo;                                 \
-    _flo.bits.frac0 = X##_f[0];                                 \
-    _flo.bits.frac1 = X##_f[1];                                 \
-    _flo.bits.frac2 = X##_f[2];                                 \
-    _flo.bits.frac3 = X##_f[3];                                 \
-    _flo.bits.exp   = X##_e;                                    \
-    _flo.bits.sign  = X##_s;                                    \
-    (val) = _flo.flt;                                          \
-  } while (0)
-
-
-/*
- * Internals
- */
-
-#define __FP_FRAC_SET_4(X,I3,I2,I1,I0)                                 \
-  (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
-
-#ifndef __FP_FRAC_ADD_4
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)   \
-  do {                                                         \
-    int _c1, _c2, _c3;                                         \
-    r0 = x0 + y0;                                              \
-    _c1 = r0 < x0;                                             \
-    r1 = x1 + y1;                                              \
-    _c2 = r1 < x1;                                             \
-    r1 += _c1;                                                 \
-    _c2 |= r1 < _c1;                                           \
-    r2 = x2 + y2;                                              \
-    _c3 = r2 < x2;                                             \
-    r2 += _c2;                                                 \
-    _c3 |= r2 < _c2;                                           \
-    r3 = x3 + y3 + _c3;                                                \
-  } while (0)
-#endif
-
-#ifndef __FP_FRAC_SUB_4
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)   \
-  do {                                                         \
-    int _c1, _c2, _c3;                                         \
-    r0 = x0 - y0;                                              \
-    _c1 = r0 > x0;                                             \
-    r1 = x1 - y1;                                              \
-    _c2 = r1 > x1;                                             \
-    r1 -= _c1;                                                 \
-    _c2 |= r1 > _c1;                                           \
-    r2 = x2 - y2;                                              \
-    _c3 = r2 > x2;                                             \
-    r2 -= _c2;                                                 \
-    _c3 |= r2 > _c2;                                           \
-    r3 = x3 - y3 - _c3;                                                \
-  } while (0)
-#endif
-
-#ifndef __FP_FRAC_ADDI_4
-/* I always wanted to be a lisp programmer :-> */
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                 \
-  (x3 += ((x2 += ((x1 += ((x0 += i) < x0)) < x1) < x2)))
-#endif
-
-/* Convert FP values between word sizes. This appears to be more
- * complicated than I'd have expected it to be, so these might be
- * wrong... These macros are in any case somewhat bogus because they
- * use information about what various FRAC_n variables look like
- * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
- * the ones in op-2.h and op-1.h.
- */
-#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
-                        _FP_WFRACBITS_##sfs);                           \
-     D##_f = S##_f[0];                                                   \
-  } while (0)
-
-#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),     \
-                        _FP_WFRACBITS_##sfs);                           \
-     D##_f0 = S##_f[0];                                                  \
-     D##_f1 = S##_f[1];                                                  \
-  } while (0)
-
-/* Assembly/disassembly for converting to/from integral types.
- * No shifting or overflow handled here.
- */
-/* Put the FP value X into r, which is an integer of size rsize. */
-#define _FP_FRAC_ASSEMBLE_4(r, X, rsize)                                \
-  do {                                                                  \
-    if (rsize <= _FP_W_TYPE_SIZE)                                       \
-      r = X##_f[0];                                                     \
-    else if (rsize <= 2*_FP_W_TYPE_SIZE)                                \
-    {                                                                   \
-      r = X##_f[1];                                                     \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[0];                                                    \
-    }                                                                   \
-    else                                                                \
-    {                                                                   \
-      /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
-      /* and int == 4words as a single case.                         */ \
-      r = X##_f[3];                                                     \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[2];                                                    \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[1];                                                    \
-      r <<= _FP_W_TYPE_SIZE;                                            \
-      r += X##_f[0];                                                    \
-    }                                                                   \
-  } while (0)
-
-/* "No disassemble Number Five!" */
-/* move an integer of size rsize into X's fractional part. We rely on
- * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
- * having to mask the values we store into it.
- */
-#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize)                             \
-  do {                                                                  \
-    X##_f[0] = r;                                                       \
-    X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);   \
-    X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
-    X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
-  } while (0)
-
-#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     D##_f[0] = S##_f;                                                  \
-     D##_f[1] = D##_f[2] = D##_f[3] = 0;                                \
-     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
-   } while (0)
-
-#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S)                               \
-   do {                                                                 \
-     D##_f[0] = S##_f0;                                                 \
-     D##_f[1] = S##_f1;                                                 \
-     D##_f[2] = D##_f[3] = 0;                                           \
-     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
-   } while (0)
-
-/* FIXME! This has to be written */
-#define _FP_SQRT_MEAT_4(R, S, T, X, q)
diff --git a/arch/powerpc/math-emu/op-common.h b/arch/powerpc/math-emu/op-common.h
deleted file mode 100644 (file)
index afb82b6..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-#define _FP_DECL(wc, X)                        \
-  _FP_I_TYPE X##_c, X##_s, X##_e;      \
-  _FP_FRAC_DECL_##wc(X)
-
-/*
- * Finish truely unpacking a native fp value by classifying the kind
- * of fp value and normalizing both the exponent and the fraction.
- */
-
-#define _FP_UNPACK_CANONICAL(fs, wc, X)                                        \
-do {                                                                   \
-  switch (X##_e)                                                       \
-  {                                                                    \
-  default:                                                             \
-    _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs;                         \
-    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);                                        \
-    X##_e -= _FP_EXPBIAS_##fs;                                         \
-    X##_c = FP_CLS_NORMAL;                                             \
-    break;                                                             \
-                                                                       \
-  case 0:                                                              \
-    if (_FP_FRAC_ZEROP_##wc(X))                                                \
-      X##_c = FP_CLS_ZERO;                                             \
-    else                                                               \
-      {                                                                        \
-       /* a denormalized number */                                     \
-       _FP_I_TYPE _shift;                                              \
-       _FP_FRAC_CLZ_##wc(_shift, X);                                   \
-       _shift -= _FP_FRACXBITS_##fs;                                   \
-       _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));                    \
-       X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;                         \
-       X##_c = FP_CLS_NORMAL;                                          \
-      }                                                                        \
-    break;                                                             \
-                                                                       \
-  case _FP_EXPMAX_##fs:                                                        \
-    if (_FP_FRAC_ZEROP_##wc(X))                                                \
-      X##_c = FP_CLS_INF;                                              \
-    else                                                               \
-      /* we don't differentiate between signaling and quiet nans */    \
-      X##_c = FP_CLS_NAN;                                              \
-    break;                                                             \
-  }                                                                    \
-} while (0)
-
-
-/*
- * Before packing the bits back into the native fp result, take care
- * of such mundane things as rounding and overflow.  Also, for some
- * kinds of fp values, the original parts may not have been fully
- * extracted -- but that is ok, we can regenerate them now.
- */
-
-#define _FP_PACK_CANONICAL(fs, wc, X)                          \
-({int __ret = 0;                                               \
-  switch (X##_c)                                               \
-  {                                                            \
-  case FP_CLS_NORMAL:                                          \
-    X##_e += _FP_EXPBIAS_##fs;                                 \
-    if (X##_e > 0)                                             \
-      {                                                                \
-       __ret |= _FP_ROUND(wc, X);                              \
-       if (_FP_FRAC_OVERP_##wc(fs, X))                         \
-         {                                                     \
-           _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));             \
-           X##_e++;                                            \
-         }                                                     \
-       else                                                    \
-         _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                   \
-       if (X##_e >= _FP_EXPMAX_##fs)                           \
-         {                                                     \
-           /* overflow to infinity */                          \
-           X##_e = _FP_EXPMAX_##fs;                            \
-           _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);            \
-            __ret |= EFLAG_OVERFLOW;                           \
-         }                                                     \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       /* we've got a denormalized number */                   \
-       X##_e = -X##_e + 1;                                     \
-       if (X##_e <= _FP_WFRACBITS_##fs)                        \
-         {                                                     \
-           _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);    \
-           _FP_FRAC_SLL_##wc(X, 1);                            \
-           if (_FP_FRAC_OVERP_##wc(fs, X))                     \
-             {                                                 \
-               X##_e = 1;                                      \
-               _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);        \
-             }                                                 \
-           else                                                \
-             {                                                 \
-               X##_e = 0;                                      \
-               _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1);           \
-                __ret |= EFLAG_UNDERFLOW;                      \
-             }                                                 \
-         }                                                     \
-       else                                                    \
-         {                                                     \
-           /* underflow to zero */                             \
-           X##_e = 0;                                          \
-           _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);            \
-            __ret |= EFLAG_UNDERFLOW;                          \
-         }                                                     \
-      }                                                                \
-    break;                                                     \
-                                                               \
-  case FP_CLS_ZERO:                                            \
-    X##_e = 0;                                                 \
-    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                   \
-    break;                                                     \
-                                                               \
-  case FP_CLS_INF:                                             \
-    X##_e = _FP_EXPMAX_##fs;                                   \
-    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                   \
-    break;                                                     \
-                                                               \
-  case FP_CLS_NAN:                                             \
-    X##_e = _FP_EXPMAX_##fs;                                   \
-    if (!_FP_KEEPNANFRACP)                                     \
-      {                                                                \
-       _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);                 \
-       X##_s = 0;                                              \
-      }                                                                \
-    else                                                       \
-      _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs;               \
-    break;                                                     \
-  }                                                            \
-  __ret;                                                       \
-})
-
-
-/*
- * Main addition routine.  The input values should be cooked.
- */
-
-#define _FP_ADD(fs, wc, R, X, Y)                                            \
-do {                                                                        \
-  switch (_FP_CLS_COMBINE(X##_c, Y##_c))                                    \
-  {                                                                         \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):                        \
-    {                                                                       \
-      /* shift the smaller number so that its exponent matches the larger */ \
-      _FP_I_TYPE diff = X##_e - Y##_e;                                      \
-                                                                            \
-      if (diff < 0)                                                         \
-       {                                                                    \
-         diff = -diff;                                                      \
-         if (diff <= _FP_WFRACBITS_##fs)                                    \
-           _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);                  \
-         else if (!_FP_FRAC_ZEROP_##wc(X))                                  \
-           _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                          \
-         else                                                               \
-           _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                         \
-         R##_e = Y##_e;                                                     \
-       }                                                                    \
-      else                                                                  \
-       {                                                                    \
-         if (diff > 0)                                                      \
-           {                                                                \
-             if (diff <= _FP_WFRACBITS_##fs)                                \
-               _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);              \
-             else if (!_FP_FRAC_ZEROP_##wc(Y))                              \
-               _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);                      \
-             else                                                           \
-               _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc);                     \
-           }                                                                \
-         R##_e = X##_e;                                                     \
-       }                                                                    \
-                                                                            \
-      R##_c = FP_CLS_NORMAL;                                                \
-                                                                            \
-      if (X##_s == Y##_s)                                                   \
-       {                                                                    \
-         R##_s = X##_s;                                                     \
-         _FP_FRAC_ADD_##wc(R, X, Y);                                        \
-         if (_FP_FRAC_OVERP_##wc(fs, R))                                    \
-           {                                                                \
-             _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);                   \
-             R##_e++;                                                       \
-           }                                                                \
-       }                                                                    \
-      else                                                                  \
-       {                                                                    \
-         R##_s = X##_s;                                                     \
-         _FP_FRAC_SUB_##wc(R, X, Y);                                        \
-         if (_FP_FRAC_ZEROP_##wc(R))                                        \
-           {                                                                \
-             /* return an exact zero */                                     \
-             if (FP_ROUNDMODE == FP_RND_MINF)                               \
-               R##_s |= Y##_s;                                              \
-             else                                                           \
-               R##_s &= Y##_s;                                              \
-             R##_c = FP_CLS_ZERO;                                           \
-           }                                                                \
-         else                                                               \
-           {                                                                \
-             if (_FP_FRAC_NEGP_##wc(R))                                     \
-               {                                                            \
-                 _FP_FRAC_SUB_##wc(R, Y, X);                                \
-                 R##_s = Y##_s;                                             \
-               }                                                            \
-                                                                            \
-             /* renormalize after subtraction */                            \
-             _FP_FRAC_CLZ_##wc(diff, R);                                    \
-             diff -= _FP_WFRACXBITS_##fs;                                   \
-             if (diff)                                                      \
-               {                                                            \
-                 R##_e -= diff;                                             \
-                 _FP_FRAC_SLL_##wc(R, diff);                                \
-               }                                                            \
-           }                                                                \
-       }                                                                    \
-      break;                                                                \
-    }                                                                       \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):                              \
-    _FP_CHOOSENAN(fs, wc, R, X, Y);                                         \
-    break;                                                                  \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):                          \
-    R##_e = X##_e;                                                          \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):                           \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):                              \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                                     \
-    _FP_FRAC_COPY_##wc(R, X);                                               \
-    R##_s = X##_s;                                                          \
-    R##_c = X##_c;                                                          \
-    break;                                                                  \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):                          \
-    R##_e = Y##_e;                                                          \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):                           \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):                              \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                                     \
-    _FP_FRAC_COPY_##wc(R, Y);                                               \
-    R##_s = Y##_s;                                                          \
-    R##_c = Y##_c;                                                          \
-    break;                                                                  \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):                              \
-    if (X##_s != Y##_s)                                                             \
-      {                                                                             \
-       /* +INF + -INF => NAN */                                             \
-       _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                              \
-       R##_s = X##_s ^ Y##_s;                                               \
-       R##_c = FP_CLS_NAN;                                                  \
-       break;                                                               \
-      }                                                                             \
-    /* FALLTHRU */                                                          \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):                           \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                                     \
-    R##_s = X##_s;                                                          \
-    R##_c = FP_CLS_INF;                                                             \
-    break;                                                                  \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):                           \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                                     \
-    R##_s = Y##_s;                                                          \
-    R##_c = FP_CLS_INF;                                                             \
-    break;                                                                  \
-                                                                            \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):                            \
-    /* make sure the sign is correct */                                             \
-    if (FP_ROUNDMODE == FP_RND_MINF)                                        \
-      R##_s = X##_s | Y##_s;                                                \
-    else                                                                    \
-      R##_s = X##_s & Y##_s;                                                \
-    R##_c = FP_CLS_ZERO;                                                    \
-    break;                                                                  \
-                                                                            \
-  default:                                                                  \
-    abort();                                                                \
-  }                                                                         \
-} while (0)
-
-
-/*
- * Main negation routine.  FIXME -- when we care about setting exception
- * bits reliably, this will not do.  We should examine all of the fp classes.
- */
-
-#define _FP_NEG(fs, wc, R, X)          \
-  do {                                 \
-    _FP_FRAC_COPY_##wc(R, X);          \
-    R##_c = X##_c;                     \
-    R##_e = X##_e;                     \
-    R##_s = 1 ^ X##_s;                 \
-  } while (0)
-
-
-/*
- * Main multiplication routine.  The input values should be cooked.
- */
-
-#define _FP_MUL(fs, wc, R, X, Y)                       \
-do {                                                   \
-  R##_s = X##_s ^ Y##_s;                               \
-  switch (_FP_CLS_COMBINE(X##_c, Y##_c))               \
-  {                                                    \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):   \
-    R##_c = FP_CLS_NORMAL;                             \
-    R##_e = X##_e + Y##_e + 1;                         \
-                                                       \
-    _FP_MUL_MEAT_##fs(R,X,Y);                          \
-                                                       \
-    if (_FP_FRAC_OVERP_##wc(fs, R))                    \
-      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);     \
-    else                                               \
-      R##_e--;                                         \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):         \
-    _FP_CHOOSENAN(fs, wc, R, X, Y);                    \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):      \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):         \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                \
-    R##_s = X##_s;                                     \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):         \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):      \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):     \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):       \
-    _FP_FRAC_COPY_##wc(R, X);                          \
-    R##_c = X##_c;                                     \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):      \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):         \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                \
-    R##_s = Y##_s;                                     \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):      \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):     \
-    _FP_FRAC_COPY_##wc(R, Y);                          \
-    R##_c = Y##_c;                                     \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                \
-    R##_c = FP_CLS_NAN;                                        \
-    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
-    break;                                             \
-                                                       \
-  default:                                             \
-    abort();                                           \
-  }                                                    \
-} while (0)
-
-
-/*
- * Main division routine.  The input values should be cooked.
- */
-
-#define _FP_DIV(fs, wc, R, X, Y)                       \
-do {                                                   \
-  R##_s = X##_s ^ Y##_s;                               \
-  switch (_FP_CLS_COMBINE(X##_c, Y##_c))               \
-  {                                                    \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):   \
-    R##_c = FP_CLS_NORMAL;                             \
-    R##_e = X##_e - Y##_e;                             \
-                                                       \
-    _FP_DIV_MEAT_##fs(R,X,Y);                          \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):         \
-    _FP_CHOOSENAN(fs, wc, R, X, Y);                    \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):      \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):         \
-  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                \
-    R##_s = X##_s;                                     \
-    _FP_FRAC_COPY_##wc(R, X);                          \
-    R##_c = X##_c;                                     \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):      \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):         \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                \
-    R##_s = Y##_s;                                     \
-    _FP_FRAC_COPY_##wc(R, Y);                          \
-    R##_c = Y##_c;                                     \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):      \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):     \
-    R##_c = FP_CLS_ZERO;                               \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):     \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):      \
-    R##_c = FP_CLS_INF;                                        \
-    break;                                             \
-                                                       \
-  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):         \
-  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):       \
-    R##_c = FP_CLS_NAN;                                        \
-    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
-    break;                                             \
-                                                       \
-  default:                                             \
-    abort();                                           \
-  }                                                    \
-} while (0)
-
-
-/*
- * Main differential comparison routine.  The inputs should be raw not
- * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
- */
-
-#define _FP_CMP(fs, wc, ret, X, Y, un)                                 \
-  do {                                                                 \
-    /* NANs are unordered */                                           \
-    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))          \
-       || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))       \
-      {                                                                        \
-       ret = un;                                                       \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-        int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;     \
-        int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;     \
-                                                                       \
-       if (__x_zero && __y_zero)                                       \
-         ret = 0;                                                      \
-       else if (__x_zero)                                              \
-         ret = Y##_s ? 1 : -1;                                         \
-       else if (__y_zero)                                              \
-         ret = X##_s ? -1 : 1;                                         \
-       else if (X##_s != Y##_s)                                        \
-         ret = X##_s ? -1 : 1;                                         \
-       else if (X##_e > Y##_e)                                         \
-         ret = X##_s ? -1 : 1;                                         \
-       else if (X##_e < Y##_e)                                         \
-         ret = X##_s ? 1 : -1;                                         \
-       else if (_FP_FRAC_GT_##wc(X, Y))                                \
-         ret = X##_s ? -1 : 1;                                         \
-       else if (_FP_FRAC_GT_##wc(Y, X))                                \
-         ret = X##_s ? 1 : -1;                                         \
-       else                                                            \
-         ret = 0;                                                      \
-      }                                                                        \
-  } while (0)
-
-
-/* Simplification for strict equality.  */
-
-#define _FP_CMP_EQ(fs, wc, ret, X, Y)                                    \
-  do {                                                                   \
-    /* NANs are unordered */                                             \
-    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))            \
-       || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))         \
-      {                                                                          \
-       ret = 1;                                                          \
-      }                                                                          \
-    else                                                                 \
-      {                                                                          \
-       ret = !(X##_e == Y##_e                                            \
-               && _FP_FRAC_EQ_##wc(X, Y)                                 \
-               && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
-      }                                                                          \
-  } while (0)
-
-/*
- * Main square root routine.  The input value should be cooked.
- */
-
-#define _FP_SQRT(fs, wc, R, X)                                         \
-do {                                                                   \
-    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);                      \
-    _FP_W_TYPE q;                                                      \
-    switch (X##_c)                                                     \
-    {                                                                  \
-    case FP_CLS_NAN:                                                   \
-       R##_s = 0;                                                      \
-       R##_c = FP_CLS_NAN;                                             \
-       _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                        \
-       break;                                                          \
-    case FP_CLS_INF:                                                   \
-       if (X##_s)                                                      \
-         {                                                             \
-           R##_s = 0;                                                  \
-           R##_c = FP_CLS_NAN; /* sNAN */                              \
-         }                                                             \
-       else                                                            \
-         {                                                             \
-           R##_s = 0;                                                  \
-           R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */                 \
-         }                                                             \
-       break;                                                          \
-    case FP_CLS_ZERO:                                                  \
-       R##_s = X##_s;                                                  \
-       R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */                      \
-       break;                                                          \
-    case FP_CLS_NORMAL:                                                        \
-       R##_s = 0;                                                      \
-        if (X##_s)                                                     \
-          {                                                            \
-           R##_c = FP_CLS_NAN; /* sNAN */                              \
-           break;                                                      \
-          }                                                            \
-       R##_c = FP_CLS_NORMAL;                                          \
-        if (X##_e & 1)                                                 \
-          _FP_FRAC_SLL_##wc(X, 1);                                     \
-        R##_e = X##_e >> 1;                                            \
-        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);                       \
-        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);                       \
-        q = _FP_OVERFLOW_##fs;                                         \
-        _FP_FRAC_SLL_##wc(X, 1);                                       \
-        _FP_SQRT_MEAT_##wc(R, S, T, X, q);                             \
-        _FP_FRAC_SRL_##wc(R, 1);                                       \
-    }                                                                  \
-  } while (0)
-
-/*
- * Convert from FP to integer
- */
-
-/* "When a NaN, infinity, large positive argument >= 2147483648.0, or
- * large negative argument <= -2147483649.0 is converted to an integer,
- * the invalid_current bit...should be set and fp_exception_IEEE_754 should
- * be raised. If the floating point invalid trap is disabled, no trap occurs
- * and a numerical result is generated: if the sign bit of the operand
- * is 0, the result is 2147483647; if the sign bit of the operand is 1,
- * the result is -2147483648."
- * Similarly for conversion to extended ints, except that the boundaries
- * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
- * -2^63 for s=1.
- * -- SPARC Architecture Manual V9, Appendix B, which specifies how
- * SPARCs resolve implementation dependencies in the IEEE-754 spec.
- * I don't believe that the code below follows this. I'm not even sure
- * it's right!
- * It doesn't cope with needing to convert to an n bit integer when there
- * is no n bit integer type. Fortunately gcc provides long long so this
- * isn't a problem for sparc32.
- * I have, however, fixed its NaN handling to conform as above.
- *         -- PMM 02/1998
- * NB: rsigned is not 'is r declared signed?' but 'should the value stored
- * in r be signed or unsigned?'. r is always(?) declared unsigned.
- * Comments below are mine, BTW -- PMM
- */
-#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)                       \
-  do {                                                                 \
-    switch (X##_c)                                                     \
-      {                                                                        \
-      case FP_CLS_NORMAL:                                              \
-       if (X##_e < 0)                                                  \
-         {                                                             \
-         /* case FP_CLS_NAN: see above! */                             \
-         case FP_CLS_ZERO:                                             \
-           r = 0;                                                      \
-         }                                                             \
-       else if (X##_e >= rsize - (rsigned != 0))                       \
-         {     /* overflow */                                          \
-         case FP_CLS_NAN:                                              \
-          case FP_CLS_INF:                                             \
-           if (rsigned)                                                \
-             {                                                         \
-               r = 1;                                                  \
-               r <<= rsize - 1;                                        \
-               r -= 1 - X##_s;                                         \
-             }                                                         \
-           else                                                        \
-             {                                                         \
-               r = 0;                                                  \
-               if (!X##_s)                                             \
-                 r = ~r;                                               \
-             }                                                         \
-         }                                                             \
-       else                                                            \
-         {                                                             \
-           if (_FP_W_TYPE_SIZE*wc < rsize)                             \
-             {                                                         \
-               _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                    \
-               r <<= X##_e - _FP_WFRACBITS_##fs;                       \
-             }                                                         \
-           else                                                        \
-             {                                                         \
-               if (X##_e >= _FP_WFRACBITS_##fs)                        \
-                 _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
-               else                                                    \
-                 _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
-               _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                    \
-             }                                                         \
-           if (rsigned && X##_s)                                       \
-             r = -r;                                                   \
-         }                                                             \
-       break;                                                          \
-      }                                                                        \
-  } while (0)
-
-#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                       \
-  do {                                                                 \
-    if (r)                                                             \
-      {                                                                        \
-       X##_c = FP_CLS_NORMAL;                                          \
-                                                                       \
-       if ((X##_s = (r < 0)))                                          \
-         r = -r;                                                       \
-       /* Note that `r' is now considered unsigned, so we don't have   \
-          to worry about the single signed overflow case.  */          \
-                                                                       \
-       if (rsize <= _FP_W_TYPE_SIZE)                                   \
-         __FP_CLZ(X##_e, r);                                           \
-       else                                                            \
-         __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE),         \
-                    (_FP_W_TYPE)r);                                    \
-       if (rsize < _FP_W_TYPE_SIZE)                                    \
-               X##_e -= (_FP_W_TYPE_SIZE - rsize);                     \
-       X##_e = rsize - X##_e - 1;                                      \
-                                                                       \
-       if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)    \
-         __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);      \
-       r &= ~((_FP_W_TYPE)1 << X##_e);                                 \
-       _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);       \
-       _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));         \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       X##_c = FP_CLS_ZERO, X##_s = 0;                                 \
-      }                                                                        \
-  } while (0)
-
-
-#define FP_CONV(dfs,sfs,dwc,swc,D,S)                   \
-  do {                                                 \
-    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);       \
-    D##_e = S##_e;                                     \
-    D##_c = S##_c;                                     \
-    D##_s = S##_s;                                     \
-  } while (0)
-
-/*
- * Helper primitives.
- */
-
-/* Count leading zeros in a word.  */
-
-#ifndef __FP_CLZ
-#if _FP_W_TYPE_SIZE < 64
-/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
-#define __FP_CLZ(r, x)                         \
-  do {                                         \
-    _FP_W_TYPE _t = (x);                       \
-    r = _FP_W_TYPE_SIZE - 1;                   \
-    if (_t > 0xffff) r -= 16;                  \
-    if (_t > 0xffff) _t >>= 16;                        \
-    if (_t > 0xff) r -= 8;                     \
-    if (_t > 0xff) _t >>= 8;                   \
-    if (_t & 0xf0) r -= 4;                     \
-    if (_t & 0xf0) _t >>= 4;                   \
-    if (_t & 0xc) r -= 2;                      \
-    if (_t & 0xc) _t >>= 2;                    \
-    if (_t & 0x2) r -= 1;                      \
-  } while (0)
-#else /* not _FP_W_TYPE_SIZE < 64 */
-#define __FP_CLZ(r, x)                         \
-  do {                                         \
-    _FP_W_TYPE _t = (x);                       \
-    r = _FP_W_TYPE_SIZE - 1;                   \
-    if (_t > 0xffffffff) r -= 32;              \
-    if (_t > 0xffffffff) _t >>= 32;            \
-    if (_t > 0xffff) r -= 16;                  \
-    if (_t > 0xffff) _t >>= 16;                        \
-    if (_t > 0xff) r -= 8;                     \
-    if (_t > 0xff) _t >>= 8;                   \
-    if (_t & 0xf0) r -= 4;                     \
-    if (_t & 0xf0) _t >>= 4;                   \
-    if (_t & 0xc) r -= 2;                      \
-    if (_t & 0xc) _t >>= 2;                    \
-    if (_t & 0x2) r -= 1;                      \
-  } while (0)
-#endif /* not _FP_W_TYPE_SIZE < 64 */
-#endif /* ndef __FP_CLZ */
-
-#define _FP_DIV_HELP_imm(q, r, n, d)           \
-  do {                                         \
-    q = n / d, r = n % d;                      \
-  } while (0)
-
diff --git a/arch/powerpc/math-emu/single.h b/arch/powerpc/math-emu/single.h
deleted file mode 100644 (file)
index f19d994..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Definitions for IEEE Single Precision
- */
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel kid.  Go buy yourself a real computer."
-#endif
-
-#define _FP_FRACBITS_S         24
-#define _FP_FRACXBITS_S                (_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
-#define _FP_WFRACBITS_S                (_FP_WORKBITS + _FP_FRACBITS_S)
-#define _FP_WFRACXBITS_S       (_FP_W_TYPE_SIZE - _FP_WFRACBITS_S)
-#define _FP_EXPBITS_S          8
-#define _FP_EXPBIAS_S          127
-#define _FP_EXPMAX_S           255
-#define _FP_QNANBIT_S          ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
-#define _FP_IMPLBIT_S          ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
-#define _FP_OVERFLOW_S         ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
-
-/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
-   chosen by the target machine.  */
-
-union _FP_UNION_S
-{
-  float flt;
-  struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
-    unsigned sign : 1;
-    unsigned exp  : _FP_EXPBITS_S;
-    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
-#else
-    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
-    unsigned exp  : _FP_EXPBITS_S;
-    unsigned sign : 1;
-#endif
-  } bits __attribute__((packed));
-};
-
-#define FP_DECL_S(X)           _FP_DECL(1,X)
-#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val)
-#define FP_PACK_RAW_S(val,X)   _FP_PACK_RAW_1(S,val,X)
-
-#define FP_UNPACK_S(X,val)             \
-  do {                                 \
-    _FP_UNPACK_RAW_1(S,X,val);         \
-    _FP_UNPACK_CANONICAL(S,1,X);       \
-  } while (0)
-
-#define FP_PACK_S(val,X)               \
-  do {                                 \
-    _FP_PACK_CANONICAL(S,1,X);         \
-    _FP_PACK_RAW_1(S,val,X);           \
-  } while (0)
-
-#define FP_NEG_S(R,X)          _FP_NEG(S,1,R,X)
-#define FP_ADD_S(R,X,Y)                _FP_ADD(S,1,R,X,Y)
-#define FP_SUB_S(R,X,Y)                _FP_SUB(S,1,R,X,Y)
-#define FP_MUL_S(R,X,Y)                _FP_MUL(S,1,R,X,Y)
-#define FP_DIV_S(R,X,Y)                _FP_DIV(S,1,R,X,Y)
-#define FP_SQRT_S(R,X)         _FP_SQRT(S,1,R,X)
-
-#define FP_CMP_S(r,X,Y,un)     _FP_CMP(S,1,r,X,Y,un)
-#define FP_CMP_EQ_S(r,X,Y)     _FP_CMP_EQ(S,1,r,X,Y)
-
-#define FP_TO_INT_S(r,X,rsz,rsg)  _FP_TO_INT(S,1,r,X,rsz,rsg)
-#define FP_FROM_INT_S(X,r,rs,rt)  _FP_FROM_INT(S,1,X,r,rs,rt)
diff --git a/arch/powerpc/math-emu/soft-fp.h b/arch/powerpc/math-emu/soft-fp.h
deleted file mode 100644 (file)
index cca3959..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef SOFT_FP_H
-#define SOFT_FP_H
-
-#include "sfp-machine.h"
-
-#define _FP_WORKBITS           3
-#define _FP_WORK_LSB           ((_FP_W_TYPE)1 << 3)
-#define _FP_WORK_ROUND         ((_FP_W_TYPE)1 << 2)
-#define _FP_WORK_GUARD         ((_FP_W_TYPE)1 << 1)
-#define _FP_WORK_STICKY                ((_FP_W_TYPE)1 << 0)
-
-#ifndef FP_RND_NEAREST
-# define FP_RND_NEAREST                0
-# define FP_RND_ZERO           1
-# define FP_RND_PINF           2
-# define FP_RND_MINF           3
-#ifndef FP_ROUNDMODE
-# define FP_ROUNDMODE          FP_RND_NEAREST
-#endif
-#endif
-
-#define _FP_ROUND_NEAREST(wc, X)                       \
-({  int __ret = 0;                                     \
-    int __frac = _FP_FRAC_LOW_##wc(X) & 15;            \
-    if (__frac & 7) {                                  \
-      __ret = EFLAG_INEXACT;                           \
-      if ((__frac & 7) != _FP_WORK_ROUND)              \
-        _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);         \
-      else if (__frac & _FP_WORK_LSB)                  \
-        _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);         \
-    }                                                  \
-    __ret;                                             \
-})
-
-#define _FP_ROUND_ZERO(wc, X)                          \
-({  int __ret = 0;                                     \
-    if (_FP_FRAC_LOW_##wc(X) & 7)                      \
-      __ret = EFLAG_INEXACT;                           \
-    __ret;                                             \
-})
-
-#define _FP_ROUND_PINF(wc, X)                          \
-({  int __ret = EFLAG_INEXACT;                         \
-    if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))          \
-      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);             \
-    else __ret = 0;                                    \
-    __ret;                                             \
-})
-
-#define _FP_ROUND_MINF(wc, X)                          \
-({  int __ret = EFLAG_INEXACT;                         \
-    if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))           \
-      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);             \
-    else __ret = 0;                                    \
-    __ret;                                             \
-})
-
-#define _FP_ROUND(wc, X)                       \
-({     int __ret = 0;                          \
-       switch (FP_ROUNDMODE)                   \
-       {                                       \
-         case FP_RND_NEAREST:                  \
-           __ret |= _FP_ROUND_NEAREST(wc,X);   \
-           break;                              \
-         case FP_RND_ZERO:                     \
-           __ret |= _FP_ROUND_ZERO(wc,X);      \
-           break;                              \
-         case FP_RND_PINF:                     \
-           __ret |= _FP_ROUND_PINF(wc,X);      \
-           break;                              \
-         case FP_RND_MINF:                     \
-           __ret |= _FP_ROUND_MINF(wc,X);      \
-           break;                              \
-       };                                      \
-       __ret;                                  \
-})
-
-#define FP_CLS_NORMAL          0
-#define FP_CLS_ZERO            1
-#define FP_CLS_INF             2
-#define FP_CLS_NAN             3
-
-#define _FP_CLS_COMBINE(x,y)   (((x) << 2) | (y))
-
-#include "op-1.h"
-#include "op-2.h"
-#include "op-4.h"
-#include "op-common.h"
-
-/* Sigh.  Silly things longlong.h needs.  */
-#define UWtype         _FP_W_TYPE
-#define W_TYPE_SIZE    _FP_W_TYPE_SIZE
-
-typedef int SItype __attribute__((mode(SI)));
-typedef int DItype __attribute__((mode(DI)));
-typedef unsigned int USItype __attribute__((mode(SI)));
-typedef unsigned int UDItype __attribute__((mode(DI)));
-#if _FP_W_TYPE_SIZE == 32
-typedef unsigned int UHWtype __attribute__((mode(HI)));
-#elif _FP_W_TYPE_SIZE == 64
-typedef USItype UHWtype;
-#endif
-
-#endif
index 8689aa48ef6952b8d45d9e3218d8bd97f7f8f71d..6122147356d1b2fa008922ae86e0fb157ce557f7 100644 (file)
@@ -2,23 +2,24 @@
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
 
 int
 stfs(void *frS, void *ea)
 {
        FP_DECL_D(A);
        FP_DECL_S(R);
+       FP_DECL_EX;
        float f;
-       int err;
 
 #ifdef DEBUG
        printk("%s: S %p, ea %p\n", __func__, frS, ea);
 #endif
 
-       __FP_UNPACK_D(A, frS);
+       FP_UNPACK_DP(A, frS);
 
 #ifdef DEBUG
        printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -30,12 +31,12 @@ stfs(void *frS, void *ea)
        printk("R: %ld %lu %ld (%ld)\n", R_s, R_f, R_e, R_c);
 #endif
 
-       err = _FP_PACK_CANONICAL(S, 1, R);
-       if (!err || !__FPU_TRAP_P(err)) {
-               __FP_PACK_RAW_1(S, &f, R);
+       _FP_PACK_CANONICAL(S, 1, R);
+       if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) {
+               _FP_PACK_RAW_1_P(S, &f, R);
                if (copy_to_user(ea, &f, sizeof(float)))
                        return -EFAULT;
        }
 
-       return err;
+       return FP_CUR_EXCEPTIONS;
 }
diff --git a/arch/powerpc/math-emu/types.c b/arch/powerpc/math-emu/types.c
deleted file mode 100644 (file)
index e1ed15d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-void
-fp_unpack_d(long *_s, unsigned long *_f1, unsigned long *_f0,
-           long *_e, long *_c, void *val)
-{
-       FP_DECL_D(X);
-
-       __FP_UNPACK_RAW_2(D, X, val);
-
-       _FP_UNPACK_CANONICAL(D, 2, X);
-
-       *_s = X_s;
-       *_f1 = X_f1;
-       *_f0 = X_f0;
-       *_e = X_e;
-       *_c = X_c;
-}
-
-int
-fp_pack_d(void *val, long X_s, unsigned long X_f1,
-         unsigned long X_f0, long X_e, long X_c)
-{
-       int exc;
-
-       exc = _FP_PACK_CANONICAL(D, 2, X);
-       if (!exc || !__FPU_TRAP_P(exc))
-               __FP_PACK_RAW_2(D, val, X);
-       return exc;
-}
-
-int
-fp_pack_ds(void *val, long X_s, unsigned long X_f1,
-          unsigned long X_f0, long X_e, long X_c)
-{
-       FP_DECL_S(__X);
-       int exc;
-
-       FP_CONV(S, D, 1, 2, __X, X);
-       exc = _FP_PACK_CANONICAL(S, 1, __X);
-       if (!exc || !__FPU_TRAP_P(exc)) {
-               _FP_UNPACK_CANONICAL(S, 1, __X);
-               FP_CONV(D, S, 2, 1, X, __X);
-               exc |= _FP_PACK_CANONICAL(D, 2, X);
-               if (!exc || !__FPU_TRAP_P(exc))
-                       __FP_PACK_RAW_2(D, val, X);
-       }
-       return exc;
-}
index 7e112dc1e2f2f81bb958dcb6cf60dafbec4ca275..6172044ab00339768dc41c69613ffbccb829ae40 100644 (file)
@@ -1,6 +1,6 @@
 /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny.  */
 
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
 
 #undef count_leading_zeros
 #define count_leading_zeros  __FP_CLZ
index ce10e2b1b902e5ddba7abcd9f48489ef1f2f862e..23cee39534fddf8ab832658e6a3f0cb658cabec8 100644 (file)
@@ -202,7 +202,7 @@ adjust_total_lowmem(void)
                cam_max_size = max_lowmem_size;
 
        /* adjust lowmem size to max_lowmem_size */
-       ram = min(max_lowmem_size, (phys_addr_t)total_lowmem);
+       ram = min(max_lowmem_size, total_lowmem);
 
        /* Calculate CAM values */
        __cam0 = 1UL << 2 * (__ilog2(ram) / 2);
@@ -225,7 +225,8 @@ adjust_total_lowmem(void)
        printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
                        " CAM2=%ldMb residual: %ldMb\n",
                        __cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
-                       (total_lowmem - __cam0 - __cam1 - __cam2) >> 20);
+                       (long int)((total_lowmem - __cam0 - __cam1 - __cam2)
+                                  >> 20));
        __max_low_memory = __cam0 + __cam1 + __cam2;
        __initial_memory_limit_addr = memstart_addr + __max_low_memory;
 }
index 9fdf4d6335e43b0388088ca2e00fe43ca8d0aff3..28a114db3ba0d9a405fbd743b3b6b86359201795 100644 (file)
@@ -41,7 +41,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
                page = pte_page(pte);
                if (!page_cache_get_speculative(page))
                        return 0;
-               if (unlikely(pte != *ptep)) {
+               if (unlikely(pte_val(pte) != pte_val(*ptep))) {
                        put_page(page);
                        return 0;
                }
@@ -92,7 +92,7 @@ static noinline int gup_huge_pte(pte_t *ptep, struct hstate *hstate,
                *nr -= refs;
                return 0;
        }
-       if (unlikely(pte != *ptep)) {
+       if (unlikely(pte_val(pte) != pte_val(*ptep))) {
                /* Could be optimized better */
                while (*nr) {
                        put_page(page);
@@ -237,7 +237,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
                        pgd_t pgd = *pgdp;
 
                        VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift);
-                       pr_debug("  %016lx: normal pgd %p\n", addr, (void *)pgd);
+                       pr_debug("  %016lx: normal pgd %p\n", addr,
+                                (void *)pgd_val(pgd));
                        next = pgd_addr_end(addr, end);
                        if (pgd_none(pgd))
                                goto slow;
index b9ba7d9308017814c97bb1b3ef920d31a63e8494..7bffb70b9fe25cd71750428578ba961561412ee6 100644 (file)
@@ -75,7 +75,7 @@ _GLOBAL(hash_page_sync)
  * Returns to the caller if the access is illegal or there is no
  * mapping for the address.  Otherwise it places an appropriate PTE
  * in the hash table and returns from the exception.
- * Uses r0, r3 - r8, ctr, lr.
+ * Uses r0, r3 - r8, r10, ctr, lr.
  */
        .text
 _GLOBAL(hash_page)
@@ -106,9 +106,15 @@ _GLOBAL(hash_page)
        addi    r5,r5,swapper_pg_dir@l  /* kernel page table */
        rlwimi  r3,r9,32-12,29,29       /* MSR_PR -> _PAGE_USER */
 112:   add     r5,r5,r7                /* convert to phys addr */
+#ifndef CONFIG_PTE_64BIT
        rlwimi  r5,r4,12,20,29          /* insert top 10 bits of address */
        lwz     r8,0(r5)                /* get pmd entry */
        rlwinm. r8,r8,0,0,19            /* extract address of pte page */
+#else
+       rlwinm  r8,r4,13,19,29          /* Compute pgdir/pmd offset */
+       lwzx    r8,r8,r5                /* Get L1 entry */
+       rlwinm. r8,r8,0,0,20            /* extract pt base address */
+#endif
 #ifdef CONFIG_SMP
        beq-    hash_page_out           /* return if no mapping */
 #else
@@ -118,7 +124,11 @@ _GLOBAL(hash_page)
           to the address following the rfi. */
        beqlr-
 #endif
+#ifndef CONFIG_PTE_64BIT
        rlwimi  r8,r4,22,20,29          /* insert next 10 bits of address */
+#else
+       rlwimi  r8,r4,23,20,28          /* compute pte address */
+#endif
        rlwinm  r0,r3,32-3,24,24        /* _PAGE_RW access -> _PAGE_DIRTY */
        ori     r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE
 
@@ -127,9 +137,15 @@ _GLOBAL(hash_page)
         * because almost always, there won't be a permission violation
         * and there won't already be an HPTE, and thus we will have
         * to update the PTE to set _PAGE_HASHPTE.  -- paulus.
+        *
+        * If PTE_64BIT is set, the low word is the flags word; use that
+        * word for locking since it contains all the interesting bits.
         */
+#if (PTE_FLAGS_OFFSET != 0)
+       addi    r8,r8,PTE_FLAGS_OFFSET
+#endif
 retry:
-       lwarx   r6,0,r8                 /* get linux-style pte */
+       lwarx   r6,0,r8                 /* get linux-style pte, flag word */
        andc.   r5,r3,r6                /* check access & ~permission */
 #ifdef CONFIG_SMP
        bne-    hash_page_out           /* return if access not permitted */
@@ -137,6 +153,15 @@ retry:
        bnelr-
 #endif
        or      r5,r0,r6                /* set accessed/dirty bits */
+#ifdef CONFIG_PTE_64BIT
+#ifdef CONFIG_SMP
+       subf    r10,r6,r8               /* create false data dependency */
+       subi    r10,r10,PTE_FLAGS_OFFSET
+       lwzx    r10,r6,r10              /* Get upper PTE word */
+#else
+       lwz     r10,-PTE_FLAGS_OFFSET(r8)
+#endif /* CONFIG_SMP */
+#endif /* CONFIG_PTE_64BIT */
        stwcx.  r5,0,r8                 /* attempt to update PTE */
        bne-    retry                   /* retry if someone got there first */
 
@@ -203,9 +228,9 @@ _GLOBAL(add_hash_page)
         * we can't take a hash table miss (assuming the code is
         * covered by a BAT).  -- paulus
         */
-       mfmsr   r10
+       mfmsr   r9
        SYNC
-       rlwinm  r0,r10,0,17,15          /* clear bit 16 (MSR_EE) */
+       rlwinm  r0,r9,0,17,15           /* clear bit 16 (MSR_EE) */
        rlwinm  r0,r0,0,28,26           /* clear MSR_DR */
        mtmsr   r0
        SYNC_601
@@ -214,14 +239,14 @@ _GLOBAL(add_hash_page)
        tophys(r7,0)
 
 #ifdef CONFIG_SMP
-       addis   r9,r7,mmu_hash_lock@ha
-       addi    r9,r9,mmu_hash_lock@l
-10:    lwarx   r0,0,r9                 /* take the mmu_hash_lock */
+       addis   r6,r7,mmu_hash_lock@ha
+       addi    r6,r6,mmu_hash_lock@l
+10:    lwarx   r0,0,r6                 /* take the mmu_hash_lock */
        cmpi    0,r0,0
        bne-    11f
-       stwcx.  r8,0,r9
+       stwcx.  r8,0,r6
        beq+    12f
-11:    lwz     r0,0(r9)
+11:    lwz     r0,0(r6)
        cmpi    0,r0,0
        beq     10b
        b       11b
@@ -234,10 +259,24 @@ _GLOBAL(add_hash_page)
         * HPTE, so we just unlock and return.
         */
        mr      r8,r5
+#ifndef CONFIG_PTE_64BIT
        rlwimi  r8,r4,22,20,29
+#else
+       rlwimi  r8,r4,23,20,28
+       addi    r8,r8,PTE_FLAGS_OFFSET
+#endif
 1:     lwarx   r6,0,r8
        andi.   r0,r6,_PAGE_HASHPTE
        bne     9f                      /* if HASHPTE already set, done */
+#ifdef CONFIG_PTE_64BIT
+#ifdef CONFIG_SMP
+       subf    r10,r6,r8               /* create false data dependency */
+       subi    r10,r10,PTE_FLAGS_OFFSET
+       lwzx    r10,r6,r10              /* Get upper PTE word */
+#else
+       lwz     r10,-PTE_FLAGS_OFFSET(r8)
+#endif /* CONFIG_SMP */
+#endif /* CONFIG_PTE_64BIT */
        ori     r5,r6,_PAGE_HASHPTE
        stwcx.  r5,0,r8
        bne-    1b
@@ -246,13 +285,15 @@ _GLOBAL(add_hash_page)
 
 9:
 #ifdef CONFIG_SMP
+       addis   r6,r7,mmu_hash_lock@ha
+       addi    r6,r6,mmu_hash_lock@l
        eieio
        li      r0,0
-       stw     r0,0(r9)                /* clear mmu_hash_lock */
+       stw     r0,0(r6)                /* clear mmu_hash_lock */
 #endif
 
        /* reenable interrupts and DR */
-       mtmsr   r10
+       mtmsr   r9
        SYNC_601
        isync
 
@@ -267,7 +308,8 @@ _GLOBAL(add_hash_page)
  * r5 contains the linux PTE, r6 contains the old value of the
  * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the
  * offset to be added to addresses (0 if the MMU is on,
- * -KERNELBASE if it is off).
+ * -KERNELBASE if it is off).  r10 contains the upper half of
+ * the PTE if CONFIG_PTE_64BIT.
  * On SMP, the caller should have the mmu_hash_lock held.
  * We assume that the caller has (or will) set the _PAGE_HASHPTE
  * bit in the linux PTE in memory.  The value passed in r6 should
@@ -285,7 +327,7 @@ Hash_bits = 12                              /* e.g. 256kB hash table */
 Hash_msk = (((1 << Hash_bits) - 1) * 64)
 
 /* defines for the PTE format for 32-bit PPCs */
-#define PTE_SIZE       8
+#define HPTE_SIZE      8
 #define PTEG_SIZE      64
 #define LG_PTEG_SIZE   6
 #define LDPTEu         lwzu
@@ -313,6 +355,11 @@ _GLOBAL(create_hpte)
 BEGIN_FTR_SECTION
        ori     r8,r8,_PAGE_COHERENT    /* set M (coherence required) */
 END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT)
+#ifdef CONFIG_PTE_64BIT
+       /* Put the XPN bits into the PTE */
+       rlwimi  r8,r10,8,20,22
+       rlwimi  r8,r10,2,29,29
+#endif
 
        /* Construct the high word of the PPC-style PTE (r5) */
        rlwinm  r5,r3,7,1,24            /* put VSID in 0x7fffff80 bits */
@@ -342,8 +389,8 @@ _GLOBAL(hash_page_patch_A)
 
        /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
        mtctr   r0
-       addi    r4,r3,-PTE_SIZE
-1:     LDPTEu  r6,PTE_SIZE(r4)         /* get next PTE */
+       addi    r4,r3,-HPTE_SIZE
+1:     LDPTEu  r6,HPTE_SIZE(r4)        /* get next PTE */
        CMPPTE  0,r6,r5
        bdnzf   2,1b                    /* loop while ctr != 0 && !cr0.eq */
        beq+    found_slot
@@ -353,9 +400,9 @@ _GLOBAL(hash_page_patch_A)
 _GLOBAL(hash_page_patch_B)
        xoris   r4,r3,Hash_msk>>16      /* compute secondary hash */
        xori    r4,r4,(-PTEG_SIZE & 0xffff)
-       addi    r4,r4,-PTE_SIZE
+       addi    r4,r4,-HPTE_SIZE
        mtctr   r0
-2:     LDPTEu  r6,PTE_SIZE(r4)
+2:     LDPTEu  r6,HPTE_SIZE(r4)
        CMPPTE  0,r6,r5
        bdnzf   2,2b
        beq+    found_slot
@@ -363,8 +410,8 @@ _GLOBAL(hash_page_patch_B)
 
        /* Search the primary PTEG for an empty slot */
 10:    mtctr   r0
-       addi    r4,r3,-PTE_SIZE         /* search primary PTEG */
-1:     LDPTEu  r6,PTE_SIZE(r4)         /* get next PTE */
+       addi    r4,r3,-HPTE_SIZE        /* search primary PTEG */
+1:     LDPTEu  r6,HPTE_SIZE(r4)        /* get next PTE */
        TST_V(r6)                       /* test valid bit */
        bdnzf   2,1b                    /* loop while ctr != 0 && !cr0.eq */
        beq+    found_empty
@@ -380,9 +427,9 @@ _GLOBAL(hash_page_patch_B)
 _GLOBAL(hash_page_patch_C)
        xoris   r4,r3,Hash_msk>>16      /* compute secondary hash */
        xori    r4,r4,(-PTEG_SIZE & 0xffff)
-       addi    r4,r4,-PTE_SIZE
+       addi    r4,r4,-HPTE_SIZE
        mtctr   r0
-2:     LDPTEu  r6,PTE_SIZE(r4)
+2:     LDPTEu  r6,HPTE_SIZE(r4)
        TST_V(r6)
        bdnzf   2,2b
        beq+    found_empty
@@ -409,11 +456,11 @@ _GLOBAL(hash_page_patch_C)
 
 1:     addis   r4,r7,next_slot@ha              /* get next evict slot */
        lwz     r6,next_slot@l(r4)
-       addi    r6,r6,PTE_SIZE                  /* search for candidate */
-       andi.   r6,r6,7*PTE_SIZE
+       addi    r6,r6,HPTE_SIZE                 /* search for candidate */
+       andi.   r6,r6,7*HPTE_SIZE
        stw     r6,next_slot@l(r4)
        add     r4,r3,r6
-       LDPTE   r0,PTE_SIZE/2(r4)               /* get PTE second word */
+       LDPTE   r0,HPTE_SIZE/2(r4)              /* get PTE second word */
        clrrwi  r0,r0,12
        lis     r6,etext@h
        ori     r6,r6,etext@l                   /* get etext */
@@ -426,7 +473,7 @@ _GLOBAL(hash_page_patch_C)
 found_empty:
        STPTE   r5,0(r4)
 found_slot:
-       STPTE   r8,PTE_SIZE/2(r4)
+       STPTE   r8,HPTE_SIZE/2(r4)
 
 #else /* CONFIG_SMP */
 /*
@@ -452,7 +499,7 @@ found_slot:
        STPTE   r5,0(r4)
        sync
        TLBSYNC
-       STPTE   r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */
+       STPTE   r8,HPTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */
        sync
        SET_V(r5)
        STPTE   r5,0(r4)        /* finally set V bit in PTE */
@@ -499,14 +546,18 @@ _GLOBAL(flush_hash_pages)
        isync
 
        /* First find a PTE in the range that has _PAGE_HASHPTE set */
+#ifndef CONFIG_PTE_64BIT
        rlwimi  r5,r4,22,20,29
-1:     lwz     r0,0(r5)
+#else
+       rlwimi  r5,r4,23,20,28
+#endif
+1:     lwz     r0,PTE_FLAGS_OFFSET(r5)
        cmpwi   cr1,r6,1
        andi.   r0,r0,_PAGE_HASHPTE
        bne     2f
        ble     cr1,19f
        addi    r4,r4,0x1000
-       addi    r5,r5,4
+       addi    r5,r5,PTE_SIZE
        addi    r6,r6,-1
        b       1b
 
@@ -545,7 +596,10 @@ _GLOBAL(flush_hash_pages)
         * already clear, we're done (for this pte).  If not,
         * clear it (atomically) and proceed.  -- paulus.
         */
-33:    lwarx   r8,0,r5                 /* fetch the pte */
+#if (PTE_FLAGS_OFFSET != 0)
+       addi    r5,r5,PTE_FLAGS_OFFSET
+#endif
+33:    lwarx   r8,0,r5                 /* fetch the pte flags word */
        andi.   r0,r8,_PAGE_HASHPTE
        beq     8f                      /* done if HASHPTE is already clear */
        rlwinm  r8,r8,0,31,29           /* clear HASHPTE bit */
@@ -562,8 +616,8 @@ _GLOBAL(flush_hash_patch_A)
        /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
        li      r0,8                    /* PTEs/group */
        mtctr   r0
-       addi    r12,r8,-PTE_SIZE
-1:     LDPTEu  r0,PTE_SIZE(r12)        /* get next PTE */
+       addi    r12,r8,-HPTE_SIZE
+1:     LDPTEu  r0,HPTE_SIZE(r12)       /* get next PTE */
        CMPPTE  0,r0,r11
        bdnzf   2,1b                    /* loop while ctr != 0 && !cr0.eq */
        beq+    3f
@@ -574,9 +628,9 @@ _GLOBAL(flush_hash_patch_A)
 _GLOBAL(flush_hash_patch_B)
        xoris   r12,r8,Hash_msk>>16     /* compute secondary hash */
        xori    r12,r12,(-PTEG_SIZE & 0xffff)
-       addi    r12,r12,-PTE_SIZE
+       addi    r12,r12,-HPTE_SIZE
        mtctr   r0
-2:     LDPTEu  r0,PTE_SIZE(r12)
+2:     LDPTEu  r0,HPTE_SIZE(r12)
        CMPPTE  0,r0,r11
        bdnzf   2,2b
        xori    r11,r11,PTE_H           /* clear H again */
@@ -590,7 +644,7 @@ _GLOBAL(flush_hash_patch_B)
 
 8:     ble     cr1,9f                  /* if all ptes checked */
 81:    addi    r6,r6,-1
-       addi    r5,r5,4                 /* advance to next pte */
+       addi    r5,r5,PTE_SIZE
        addi    r4,r4,0x1000
        lwz     r0,0(r5)                /* check next pte */
        cmpwi   cr1,r6,1
index 8920eea3452844dfb906fc3f9d6b67a01d37561f..5c64af1747525d7b7b5fd0adbae202845564f9e1 100644 (file)
@@ -194,7 +194,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                unsigned long tprot = prot;
 
                /* Make kernel text executable */
-               if (in_kernel_text(vaddr))
+               if (overlaps_kernel_text(vaddr, vaddr + step))
                        tprot &= ~HPTE_R_N;
 
                hash = hpt_hash(va, shift, ssize);
@@ -348,6 +348,7 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
        return 0;
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
 /* Scan for 16G memory blocks that have been set aside for huge pages
  * and reserve those blocks for 16G huge pages.
  */
@@ -385,6 +386,7 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
        add_gpage(phys_addr, block_size, expected_pages);
        return 0;
 }
+#endif /* CONFIG_HUGETLB_PAGE */
 
 static void __init htab_init_page_sizes(void)
 {
@@ -539,7 +541,7 @@ static unsigned long __init htab_get_table_size(void)
 void create_section_mapping(unsigned long start, unsigned long end)
 {
        BUG_ON(htab_bolt_mapping(start, end, __pa(start),
-                                PAGE_KERNEL, mmu_linear_psize,
+                                pgprot_val(PAGE_KERNEL), mmu_linear_psize,
                                 mmu_kernel_ssize));
 }
 
@@ -647,7 +649,7 @@ void __init htab_initialize(void)
                mtspr(SPRN_SDR1, _SDR1);
        }
 
-       prot = PAGE_KERNEL;
+       prot = pgprot_val(PAGE_KERNEL);
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
        linear_map_hash_count = lmb_end_of_DRAM() >> PAGE_SHIFT;
index f1c2d55b4377c1a09af0e860316e80d56f6557e2..a117024ab8cdb68af98c8bfc13f822695dc4c2bf 100644 (file)
@@ -128,29 +128,37 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
        return 0;
 }
 
-/* Base page size affects how we walk hugetlb page tables */
-#ifdef CONFIG_PPC_64K_PAGES
-#define hpmd_offset(pud, addr, h)      pmd_offset(pud, addr)
-#define hpmd_alloc(mm, pud, addr, h)   pmd_alloc(mm, pud, addr)
-#else
-static inline
-pmd_t *hpmd_offset(pud_t *pud, unsigned long addr, struct hstate *hstate)
+
+static pud_t *hpud_offset(pgd_t *pgd, unsigned long addr, struct hstate *hstate)
+{
+       if (huge_page_shift(hstate) < PUD_SHIFT)
+               return pud_offset(pgd, addr);
+       else
+               return (pud_t *) pgd;
+}
+static pud_t *hpud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long addr,
+                        struct hstate *hstate)
 {
-       if (huge_page_shift(hstate) == PAGE_SHIFT_64K)
+       if (huge_page_shift(hstate) < PUD_SHIFT)
+               return pud_alloc(mm, pgd, addr);
+       else
+               return (pud_t *) pgd;
+}
+static pmd_t *hpmd_offset(pud_t *pud, unsigned long addr, struct hstate *hstate)
+{
+       if (huge_page_shift(hstate) < PMD_SHIFT)
                return pmd_offset(pud, addr);
        else
                return (pmd_t *) pud;
 }
-static inline
-pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr,
-                 struct hstate *hstate)
+static pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr,
+                        struct hstate *hstate)
 {
-       if (huge_page_shift(hstate) == PAGE_SHIFT_64K)
+       if (huge_page_shift(hstate) < PMD_SHIFT)
                return pmd_alloc(mm, pud, addr);
        else
                return (pmd_t *) pud;
 }
-#endif
 
 /* Build list of addresses of gigantic pages.  This function is used in early
  * boot before the buddy or bootmem allocator is setup.
@@ -204,7 +212,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 
        pg = pgd_offset(mm, addr);
        if (!pgd_none(*pg)) {
-               pu = pud_offset(pg, addr);
+               pu = hpud_offset(pg, addr, hstate);
                if (!pud_none(*pu)) {
                        pm = hpmd_offset(pu, addr, hstate);
                        if (!pmd_none(*pm))
@@ -233,7 +241,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
        addr &= hstate->mask;
 
        pg = pgd_offset(mm, addr);
-       pu = pud_alloc(mm, pg, addr);
+       pu = hpud_alloc(mm, pg, addr, hstate);
 
        if (pu) {
                pm = hpmd_alloc(mm, pu, addr, hstate);
@@ -316,13 +324,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
        pud = pud_offset(pgd, addr);
        do {
                next = pud_addr_end(addr, end);
-#ifdef CONFIG_PPC_64K_PAGES
-               if (pud_none_or_clear_bad(pud))
-                       continue;
-               hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling,
-                                      psize);
-#else
-               if (shift == PAGE_SHIFT_64K) {
+               if (shift < PMD_SHIFT) {
                        if (pud_none_or_clear_bad(pud))
                                continue;
                        hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
@@ -332,7 +334,6 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
                                continue;
                        free_hugepte_range(tlb, (hugepd_t *)pud, psize);
                }
-#endif
        } while (pud++, addr = next, addr != end);
 
        start &= PGDIR_MASK;
@@ -422,9 +423,15 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
                psize = get_slice_psize(tlb->mm, addr);
                BUG_ON(!mmu_huge_psizes[psize]);
                next = pgd_addr_end(addr, end);
-               if (pgd_none_or_clear_bad(pgd))
-                       continue;
-               hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
+               if (mmu_psize_to_shift(psize) < PUD_SHIFT) {
+                       if (pgd_none_or_clear_bad(pgd))
+                               continue;
+                       hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
+               } else {
+                       if (pgd_none(*pgd))
+                               continue;
+                       free_hugepte_range(tlb, (hugepd_t *)pgd, psize);
+               }
        } while (pgd++, addr = next, addr != end);
 }
 
index 036fe2f10c7780c59545f72ac3f718b59fecd7cc..3e6a6543f53a9fa193d49081d1d6fcb3b8353776 100644 (file)
@@ -228,8 +228,8 @@ int __meminit vmemmap_populate(struct page *start_page,
                        start, p, __pa(p));
 
                mapped = htab_bolt_mapping(start, start + page_size, __pa(p),
-                                          PAGE_KERNEL, mmu_vmemmap_psize,
-                                          mmu_kernel_ssize);
+                                          pgprot_val(PAGE_KERNEL),
+                                          mmu_vmemmap_psize, mmu_kernel_ssize);
                BUG_ON(mapped < 0);
        }
 
index 1c93c255873b5a4fb9640dd2de7d58332dfabded..98d7bf99533aff312712d747beed29141294608d 100644 (file)
@@ -75,11 +75,10 @@ static inline pte_t *virt_to_kpte(unsigned long vaddr)
 
 int page_is_ram(unsigned long pfn)
 {
-       unsigned long paddr = (pfn << PAGE_SHIFT);
-
 #ifndef CONFIG_PPC64   /* XXX for now */
-       return paddr < __pa(high_memory);
+       return pfn < max_pfn;
 #else
+       unsigned long paddr = (pfn << PAGE_SHIFT);
        int i;
        for (i=0; i < lmb.memory.cnt; i++) {
                unsigned long base;
index d9a1813513322889af782dd71625f46db3bab1c4..6cf5c71c431fddc43d33ba920753023d847a991e 100644 (file)
@@ -89,6 +89,46 @@ static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
        return 0;
 }
 
+/*
+ * get_active_region_work_fn - A helper function for get_node_active_region
+ *     Returns datax set to the start_pfn and end_pfn if they contain
+ *     the initial value of datax->start_pfn between them
+ * @start_pfn: start page(inclusive) of region to check
+ * @end_pfn: end page(exclusive) of region to check
+ * @datax: comes in with ->start_pfn set to value to search for and
+ *     goes out with active range if it contains it
+ * Returns 1 if search value is in range else 0
+ */
+static int __init get_active_region_work_fn(unsigned long start_pfn,
+                                       unsigned long end_pfn, void *datax)
+{
+       struct node_active_region *data;
+       data = (struct node_active_region *)datax;
+
+       if (start_pfn <= data->start_pfn && end_pfn > data->start_pfn) {
+               data->start_pfn = start_pfn;
+               data->end_pfn = end_pfn;
+               return 1;
+       }
+       return 0;
+
+}
+
+/*
+ * get_node_active_region - Return active region containing start_pfn
+ * @start_pfn: The page to return the region for.
+ * @node_ar: Returned set to the active region containing start_pfn
+ */
+static void __init get_node_active_region(unsigned long start_pfn,
+                      struct node_active_region *node_ar)
+{
+       int nid = early_pfn_to_nid(start_pfn);
+
+       node_ar->nid = nid;
+       node_ar->start_pfn = start_pfn;
+       work_with_active_regions(nid, get_active_region_work_fn, node_ar);
+}
+
 static void __cpuinit map_cpu_to_node(int cpu, int node)
 {
        numa_cpu_lookup_table[cpu] = node;
@@ -150,6 +190,21 @@ static const int *of_get_associativity(struct device_node *dev)
        return of_get_property(dev, "ibm,associativity", NULL);
 }
 
+/*
+ * Returns the property linux,drconf-usable-memory if
+ * it exists (the property exists only in kexec/kdump kernels,
+ * added by kexec-tools)
+ */
+static const u32 *of_get_usable_memory(struct device_node *memory)
+{
+       const u32 *prop;
+       u32 len;
+       prop = of_get_property(memory, "linux,drconf-usable-memory", &len);
+       if (!prop || len < sizeof(unsigned int))
+               return 0;
+       return prop;
+}
+
 /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
  * info is found.
  */
@@ -486,15 +541,30 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start,
        return lmb_end_of_DRAM() - start;
 }
 
+/*
+ * Reads the counter for a given entry in
+ * linux,drconf-usable-memory property
+ */
+static inline int __init read_usm_ranges(const u32 **usm)
+{
+       /*
+        * For each lmb in ibm,dynamic-memory a corresponding
+        * entry in linux,drconf-usable-memory property contains
+        * a counter followed by that many (base, size) duple.
+        * read the counter from linux,drconf-usable-memory
+        */
+       return read_n_cells(n_mem_size_cells, usm);
+}
+
 /*
  * Extract NUMA information from the ibm,dynamic-reconfiguration-memory
  * node.  This assumes n_mem_{addr,size}_cells have been set.
  */
 static void __init parse_drconf_memory(struct device_node *memory)
 {
-       const u32 *dm;
-       unsigned int n, rc;
-       unsigned long lmb_size, size;
+       const u32 *dm, *usm;
+       unsigned int n, rc, ranges, is_kexec_kdump = 0;
+       unsigned long lmb_size, base, size, sz;
        int nid;
        struct assoc_arrays aa;
 
@@ -510,6 +580,11 @@ static void __init parse_drconf_memory(struct device_node *memory)
        if (rc)
                return;
 
+       /* check if this is a kexec/kdump kernel */
+       usm = of_get_usable_memory(memory);
+       if (usm != NULL)
+               is_kexec_kdump = 1;
+
        for (; n != 0; --n) {
                struct of_drconf_cell drmem;
 
@@ -521,21 +596,31 @@ static void __init parse_drconf_memory(struct device_node *memory)
                    || !(drmem.flags & DRCONF_MEM_ASSIGNED))
                        continue;
 
-               nid = of_drconf_to_nid_single(&drmem, &aa);
+               base = drmem.base_addr;
+               size = lmb_size;
+               ranges = 1;
 
-               fake_numa_create_new_node(
-                               ((drmem.base_addr + lmb_size) >> PAGE_SHIFT),
+               if (is_kexec_kdump) {
+                       ranges = read_usm_ranges(&usm);
+                       if (!ranges) /* there are no (base, size) duple */
+                               continue;
+               }
+               do {
+                       if (is_kexec_kdump) {
+                               base = read_n_cells(n_mem_addr_cells, &usm);
+                               size = read_n_cells(n_mem_size_cells, &usm);
+                       }
+                       nid = of_drconf_to_nid_single(&drmem, &aa);
+                       fake_numa_create_new_node(
+                               ((base + size) >> PAGE_SHIFT),
                                           &nid);
-
-               node_set_online(nid);
-
-               size = numa_enforce_memory_limit(drmem.base_addr, lmb_size);
-               if (!size)
-                       continue;
-
-               add_active_range(nid, drmem.base_addr >> PAGE_SHIFT,
-                                (drmem.base_addr >> PAGE_SHIFT)
-                                + (size >> PAGE_SHIFT));
+                       node_set_online(nid);
+                       sz = numa_enforce_memory_limit(base, size);
+                       if (sz)
+                               add_active_range(nid, base >> PAGE_SHIFT,
+                                                (base >> PAGE_SHIFT)
+                                                + (sz >> PAGE_SHIFT));
+               } while (--ranges);
        }
 }
 
@@ -837,38 +922,50 @@ void __init do_init_bootmem(void)
                                  start_pfn, end_pfn);
 
                free_bootmem_with_active_regions(nid, end_pfn);
+       }
 
-               /* Mark reserved regions on this node */
-               for (i = 0; i < lmb.reserved.cnt; i++) {
-                       unsigned long physbase = lmb.reserved.region[i].base;
-                       unsigned long size = lmb.reserved.region[i].size;
-                       unsigned long start_paddr = start_pfn << PAGE_SHIFT;
-                       unsigned long end_paddr = end_pfn << PAGE_SHIFT;
-
-                       if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid &&
-                           early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid)
-                               continue;
-
-                       if (physbase < end_paddr &&
-                           (physbase+size) > start_paddr) {
-                               /* overlaps */
-                               if (physbase < start_paddr) {
-                                       size -= start_paddr - physbase;
-                                       physbase = start_paddr;
-                               }
-
-                               if (size > end_paddr - physbase)
-                                       size = end_paddr - physbase;
-
-                               dbg("reserve_bootmem %lx %lx\n", physbase,
-                                   size);
-                               reserve_bootmem_node(NODE_DATA(nid), physbase,
-                                                    size, BOOTMEM_DEFAULT);
-                       }
+       /* Mark reserved regions */
+       for (i = 0; i < lmb.reserved.cnt; i++) {
+               unsigned long physbase = lmb.reserved.region[i].base;
+               unsigned long size = lmb.reserved.region[i].size;
+               unsigned long start_pfn = physbase >> PAGE_SHIFT;
+               unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
+               struct node_active_region node_ar;
+
+               get_node_active_region(start_pfn, &node_ar);
+               while (start_pfn < end_pfn) {
+                       /*
+                        * if reserved region extends past active region
+                        * then trim size to active region
+                        */
+                       if (end_pfn > node_ar.end_pfn)
+                               size = (node_ar.end_pfn << PAGE_SHIFT)
+                                       - (start_pfn << PAGE_SHIFT);
+                       dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size,
+                               node_ar.nid);
+                       reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
+                                               size, BOOTMEM_DEFAULT);
+                       /*
+                        * if reserved region is contained in the active region
+                        * then done.
+                        */
+                       if (end_pfn <= node_ar.end_pfn)
+                               break;
+
+                       /*
+                        * reserved region extends past the active region
+                        *   get next active region that contains this
+                        *   reserved region
+                        */
+                       start_pfn = node_ar.end_pfn;
+                       physbase = start_pfn << PAGE_SHIFT;
+                       get_node_active_region(start_pfn, &node_ar);
                }
 
-               sparse_memory_present_with_active_regions(nid);
        }
+
+       for_each_online_node(nid)
+               sparse_memory_present_with_active_regions(nid);
 }
 
 void __init paging_init(void)
index 2001abdb1912bec23dfa6635010359edddf4423b..c31d6d26f0b57c50b5b38bdc042f7221a93adf82 100644 (file)
@@ -73,7 +73,7 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
 #endif /* HAVE_TLBCAM */
 
 #ifdef CONFIG_PTE_64BIT
-/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
+/* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */
 #define PGDIR_ORDER    1
 #else
 #define PGDIR_ORDER    0
@@ -288,7 +288,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
 }
 
 /*
- * Map in all of physical memory starting at KERNELBASE.
+ * Map in a big chunk of physical memory starting at KERNELBASE.
  */
 void __init mapin_ram(void)
 {
index eb4b512d65fabc4a2b6b291d04d8dacac08e9813..f9a47fee39278174872a30a7844ff2b01c99d4c1 100644 (file)
@@ -45,6 +45,7 @@ void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr)
                flush_hash_pages(mm->context.id, addr, ptephys, 1);
        }
 }
+EXPORT_SYMBOL(flush_hash_entry);
 
 /*
  * Called by ptep_set_access_flags, must flush on CPUs for which the
index fff66662d021ed152c1e17601cb319bd3f4c6ec8..258fa4411e9e48dde2c9bfdffce352c49e3d9a21 100644 (file)
@@ -229,7 +229,7 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
         */
        overlay_tbl_offset = vma_map_lookup(map, ovly_table_sym,
                                            aSpu, &grd_val);
-       if (overlay_tbl_offset 0) {
+       if (overlay_tbl_offset > 0x10000000) {
                printk(KERN_ERR "SPU_PROF: "
                       "%s, line %d: Error finding SPU overlay table\n",
                       __func__, __LINE__);
index 446a8bbb847b0f2dcd679ac74eaece531cee4476..3e3d91f536e0be0daa3a1b7e031023de475ea5a3 100644 (file)
@@ -64,7 +64,7 @@ static int power4_reg_setup(struct op_counter_config *ctr,
        return 0;
 }
 
-extern void ppc64_enable_pmcs(void);
+extern void ppc_enable_pmcs(void);
 
 /*
  * Older CPUs require the MMCRA sample bit to be always set, but newer 
@@ -91,7 +91,7 @@ static int power4_cpu_setup(struct op_counter_config *ctr)
        unsigned int mmcr0 = mmcr0_val;
        unsigned long mmcra = mmcra_val;
 
-       ppc64_enable_pmcs();
+       ppc_enable_pmcs();
 
        /* set the freeze bit */
        mmcr0 |= MMCR0_FC;
index 249ba01c667416cfb62f8743f2701f087732b088..79c1154f88d42464796c3dd0d5ce8194a8c7862c 100644 (file)
@@ -2,6 +2,7 @@ config BAMBOO
        bool "Bamboo"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 440EP
        select PCI
        help
@@ -30,6 +31,7 @@ config SEQUOIA
        bool "Sequoia"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 440EPX
        help
          This option enables support for the AMCC PPC440EPX evaluation board.
@@ -38,6 +40,7 @@ config TAISHAN
        bool "Taishan"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 440GX
        select PCI
        help
@@ -48,6 +51,7 @@ config KATMAI
        bool "Katmai"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 440SPe
        select PCI
        select PPC4xx_PCI_EXPRESS
@@ -58,6 +62,7 @@ config RAINIER
        bool "Rainier"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 440GRX
        select PCI
        help
@@ -76,20 +81,48 @@ config WARP
          See http://www.pikatechnologies.com/ and follow the "PIKA for Computer
          Telephony Developers" link for more information.
 
+config ARCHES
+       bool "Arches"
+       depends on 44x
+       default n
+       select PPC44x_SIMPLE
+       select 460EX # Odd since it uses 460GT but the effects are the same
+       select PCI
+       select PPC4xx_PCI_EXPRESS
+       help
+         This option enables support for the AMCC Dual PPC460GT evaluation board.
+
 config CANYONLANDS
        bool "Canyonlands"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 460EX
        select PCI
        select PPC4xx_PCI_EXPRESS
+       select IBM_NEW_EMAC_RGMII
+       select IBM_NEW_EMAC_ZMII
        help
          This option enables support for the AMCC PPC460EX evaluation board.
 
+config GLACIER
+       bool "Glacier"
+       depends on 44x
+       default n
+       select PPC44x_SIMPLE
+       select 460EX # Odd since it uses 460GT but the effects are the same
+       select PCI
+       select PPC4xx_PCI_EXPRESS
+       select IBM_NEW_EMAC_RGMII
+       select IBM_NEW_EMAC_ZMII
+       help
+         This option enables support for the AMCC PPC460GT evaluation board.
+
 config YOSEMITE
        bool "Yosemite"
        depends on 44x
        default n
+       select PPC44x_SIMPLE
        select 440EP
        select PCI
        help
@@ -127,6 +160,13 @@ config XILINX_VIRTEX440_GENERIC_BOARD
          Most Virtex 5 designs should use this unless it needs to do some
          special configuration at board probe time.
 
+config PPC44x_SIMPLE
+       bool "Simple PowerPC 44x board support"
+       depends on 44x
+       default n
+       help
+         This option enables the simple PowerPC 44x platform support.
+
 # 44x specific CPU modules, selected based on the board above.
 config 440EP
        bool
@@ -170,8 +210,6 @@ config 460EX
        bool
        select PPC_FPU
        select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII
        select IBM_NEW_EMAC_TAH
 
 # 44x errata/workaround config symbols, selected by the CPU models above
index 8d0b1a192d626826a60dd9c6128b0423b472c60b..698133180aee5da1a35fb8eb4df181edac4b0833 100644 (file)
@@ -1,13 +1,7 @@
 obj-$(CONFIG_44x)      := misc_44x.o idle.o
+obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o
 obj-$(CONFIG_EBONY)    += ebony.o
-obj-$(CONFIG_TAISHAN)  += taishan.o
-obj-$(CONFIG_BAMBOO)   += bamboo.o
-obj-$(CONFIG_YOSEMITE) += bamboo.o
 obj-$(CONFIG_SAM440EP)         += sam440ep.o
-obj-$(CONFIG_SEQUOIA)  += sequoia.o
-obj-$(CONFIG_KATMAI)   += katmai.o
-obj-$(CONFIG_RAINIER)  += rainier.o
 obj-$(CONFIG_WARP)     += warp.o
 obj-$(CONFIG_WARP)     += warp-nand.o
-obj-$(CONFIG_CANYONLANDS) += canyonlands.o
 obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
diff --git a/arch/powerpc/platforms/44x/bamboo.c b/arch/powerpc/platforms/44x/bamboo.c
deleted file mode 100644 (file)
index cef169e..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Bamboo board specific routines
- *
- * Wade Farnsworth <wfarnsworth@mvista.com>
- * Copyright 2004 MontaVista Software Inc.
- *
- * Rewritten and ported to the merged powerpc tree:
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id bamboo_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init bamboo_device_probe(void)
-{
-       of_platform_bus_probe(NULL, bamboo_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(bamboo, bamboo_device_probe);
-
-static int __init bamboo_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,bamboo"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(bamboo) {
-       .name                   = "Bamboo",
-       .probe                  = bamboo_probe,
-       .progress               = udbg_progress,
-       .init_IRQ               = uic_init_tree,
-       .get_irq                = uic_get_irq,
-       .restart                = ppc4xx_reset_system,
-       .calibrate_decr         = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/44x/canyonlands.c b/arch/powerpc/platforms/44x/canyonlands.c
deleted file mode 100644 (file)
index 3949289..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Canyonlands board specific routines
- *
- * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Katmai code by
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * Copyright 2007 IBM Corp.
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id canyonlands_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init canyonlands_device_probe(void)
-{
-       of_platform_bus_probe(NULL, canyonlands_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(canyonlands, canyonlands_device_probe);
-
-static int __init canyonlands_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,canyonlands"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(canyonlands) {
-       .name                           = "Canyonlands",
-       .probe                          = canyonlands_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/44x/katmai.c b/arch/powerpc/platforms/44x/katmai.c
deleted file mode 100644 (file)
index 44f4b3a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Katmai board specific routines
- *
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * Copyright 2007 IBM Corp.
- *
- * Based on the Bamboo code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id katmai_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init katmai_device_probe(void)
-{
-       of_platform_bus_probe(NULL, katmai_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(katmai, katmai_device_probe);
-
-static int __init katmai_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,katmai"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(katmai) {
-       .name                           = "Katmai",
-       .probe                          = katmai_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
new file mode 100644 (file)
index 0000000..2967126
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Generic PowerPC 44x platform support
+ *
+ * Copyright 2008 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This implements simple platform support for PowerPC 44x chips.  This is
+ * mostly used for eval boards or other simple and "generic" 44x boards.  If
+ * your board has custom functions or hardware, then you will likely want to
+ * implement your own board.c file to accommodate it.
+ */
+
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc4xx.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+#include <asm/uic.h>
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+
+static __initdata struct of_device_id ppc44x_of_bus[] = {
+       { .compatible = "ibm,plb4", },
+       { .compatible = "ibm,opb", },
+       { .compatible = "ibm,ebc", },
+       { .compatible = "simple-bus", },
+       {},
+};
+
+static int __init ppc44x_device_probe(void)
+{
+       of_platform_bus_probe(NULL, ppc44x_of_bus, NULL);
+
+       return 0;
+}
+machine_device_initcall(ppc44x_simple, ppc44x_device_probe);
+
+/* This is the list of boards that can be supported by this simple
+ * platform code.  This does _not_ mean the boards are compatible,
+ * as they most certainly are not from a device tree perspective.
+ * However, their differences are handled by the device tree and the
+ * drivers and therefore they don't need custom board support files.
+ *
+ * Again, if your board needs to do things differently then create a
+ * board.c file for it rather than adding it to this list.
+ */
+static char *board[] __initdata = {
+       "amcc,arches",
+       "amcc,bamboo",
+       "amcc,canyonlands",
+       "amcc,glacier",
+       "ibm,ebony",
+       "amcc,katmai",
+       "amcc,rainier",
+       "amcc,sequoia",
+       "amcc,taishan",
+       "amcc,yosemite"
+};
+
+static int __init ppc44x_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+       int i = 0;
+
+       for (i = 0; i < ARRAY_SIZE(board); i++) {
+               if (of_flat_dt_is_compatible(root, board[i])) {
+                       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+define_machine(ppc44x_simple) {
+       .name = "PowerPC 44x Platform",
+       .probe = ppc44x_probe,
+       .progress = udbg_progress,
+       .init_IRQ = uic_init_tree,
+       .get_irq = uic_get_irq,
+       .restart = ppc4xx_reset_system,
+       .calibrate_decr = generic_calibrate_decr,
+};
diff --git a/arch/powerpc/platforms/44x/rainier.c b/arch/powerpc/platforms/44x/rainier.c
deleted file mode 100644 (file)
index 4f1ff84..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Rainier board specific routines
- *
- * Valentine Barshak <vbarshak@ru.mvista.com>
- * Copyright 2007 MontaVista Software Inc.
- *
- * Based on the Bamboo code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id rainier_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init rainier_device_probe(void)
-{
-       of_platform_bus_probe(NULL, rainier_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(rainier, rainier_device_probe);
-
-static int __init rainier_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,rainier"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(rainier) {
-       .name                           = "Rainier",
-       .probe                          = rainier_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/44x/sequoia.c b/arch/powerpc/platforms/44x/sequoia.c
deleted file mode 100644 (file)
index 49eb73d..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Sequoia board specific routines
- *
- * Valentine Barshak <vbarshak@ru.mvista.com>
- * Copyright 2007 MontaVista Software Inc.
- *
- * Based on the Bamboo code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id sequoia_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init sequoia_device_probe(void)
-{
-       of_platform_bus_probe(NULL, sequoia_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(sequoia, sequoia_device_probe);
-
-static int __init sequoia_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,sequoia"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(sequoia) {
-       .name                           = "Sequoia",
-       .probe                          = sequoia_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/44x/taishan.c b/arch/powerpc/platforms/44x/taishan.c
deleted file mode 100644 (file)
index 49c78b2..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Taishan board specific routines based off ebony.c code
- * original copyrights below
- *
- * Matt Porter <mporter@kernel.crashing.org>
- * Copyright 2002-2005 MontaVista Software Inc.
- *
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- * Copyright (c) 2003-2005 Zultys Technologies
- *
- * Rewritten and ported to the merged powerpc tree:
- * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
- *
- * Modified from ebony.c for taishan:
- * Copyright 2007 Hugh Blemings <hugh@au.ibm.com>, IBM Corporation.
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id taishan_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init taishan_device_probe(void)
-{
-       of_platform_bus_probe(NULL, taishan_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(taishan, taishan_device_probe);
-
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init taishan_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,taishan"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(taishan) {
-       .name                   = "Taishan",
-       .probe                  = taishan_probe,
-       .progress               = udbg_progress,
-       .init_IRQ               = uic_init_tree,
-       .get_irq                = uic_get_irq,
-       .restart                = ppc4xx_reset_system,
-       .calibrate_decr         = generic_calibrate_decr,
-};
index c62f893ede190f984c6d235304b196651fb3b3c6..326852c78b8fa79caf1349f0e1776b955285a26c 100644 (file)
@@ -3,6 +3,8 @@ config PPC_MPC512x
        select FSL_SOC
        select IPIC
        select PPC_CLOCK
+       select PPC_PCI_CHOICE
+       select FSL_PCI if PCI
 
 config PPC_MPC5121
        bool
index 5ebf6939a6975ba593b1d4b1372a5ebd19c68a11..441abc488851c9f95bf6b674b7198041bf2cd79f 100644 (file)
 #include <asm/prom.h>
 #include <asm/time.h>
 
+#include <sysdev/fsl_pci.h>
+
 #include "mpc512x.h"
 #include "mpc5121_ads.h"
 
 static void __init mpc5121_ads_setup_arch(void)
 {
+#ifdef CONFIG_PCI
+       struct device_node *np;
+#endif
        printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n");
        /*
         * cpld regs are needed early
         */
        mpc5121_ads_cpld_map();
+
+#ifdef CONFIG_PCI
+       for_each_compatible_node(np, "pci", "fsl,mpc5121-pci")
+               mpc83xx_add_bridge(np);
+#endif
 }
 
 static void __init mpc5121_ads_init_IRQ(void)
index 4d5fd1dbd4007a5235b5b170367e451cc4f40b67..044b4e6e874383a77e31fe5e80d8737a465865c5 100644 (file)
@@ -90,7 +90,7 @@ mpc5200_setup_xlb_arbiter(void)
        of_node_put(np);
        if (!xlb) {
                printk(KERN_ERR __FILE__ ": "
-                       "Error mapping XLB in mpc52xx_setup_cpu().  "
+                       "Error mapping XLB in mpc52xx_setup_cpu(). "
                        "Expect some abnormal behavior\n");
                return;
        }
@@ -216,7 +216,8 @@ mpc52xx_restart(char *cmd)
                out_be32(&mpc52xx_wdt->count, 0x000000ff);
                out_be32(&mpc52xx_wdt->mode, 0x00009004);
        } else
-               printk("mpc52xx_restart: Can't access wdt. "
+               printk(KERN_ERR __FILE__ ": "
+                       "mpc52xx_restart: Can't access wdt. "
                        "Restart impossible, system halted.\n");
 
        while (1);
index 5a382bb15f6266a8c8835c9e8eef4d2951dc84ae..b49a1852766131655a57effc2514439225ba6b9c 100644 (file)
@@ -265,8 +265,11 @@ mpc52xx_pci_setup(struct pci_controller *hose,
        /* Memory windows */
        res = &hose->mem_resources[0];
        if (res->flags) {
-               pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
-                        res->start, res->end, res->flags);
+               pr_debug("mem_resource[0] = "
+                        "{.start=%llx, .end=%llx, .flags=%llx}\n",
+                        (unsigned long long)res->start,
+                        (unsigned long long)res->end,
+                        (unsigned long long)res->flags);
                out_be32(&pci_regs->iw0btar,
                         MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
                                  res->end - res->start + 1));
@@ -297,9 +300,11 @@ mpc52xx_pci_setup(struct pci_controller *hose,
                printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
                return;
        }
-       pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
+       pr_debug(".io_resource={.start=%llx,.end=%llx,.flags=%llx} "
                 ".io_base_phys=0x%p\n",
-                res->start, res->end, res->flags, (void*)hose->io_base_phys);
+                (unsigned long long)res->start,
+                (unsigned long long)res->end,
+                (unsigned long long)res->flags, (void*)hose->io_base_phys);
        out_be32(&pci_regs->iw2btar,
                 MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
                                                res->start,
index 75eb1ede54978a26af11f5fc791febbb459aa647..30f008b2f92e825f64cd518defc8bab99a9bb892 100644 (file)
@@ -38,6 +38,14 @@ config EP8248E
          This board is also resold by Freescale as the QUICCStart
          MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE.
 
+config MGCOGE
+       bool "Keymile MGCOGE"
+       select 8272
+       select 8260
+       select FSL_SOC
+       help
+         This enables support for the Keymile MGCOGE board.
+
 endif
 
 config PQ2ADS
index 6cd5cd59bf2a4abaa2d4901b176fe7c5994a86a4..d982793f4dbd111b0535436ee39deb06c1cb40ca 100644 (file)
@@ -6,3 +6,4 @@ obj-$(CONFIG_CPM2) += pq2.o
 obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o
 obj-$(CONFIG_PQ2FADS) += pq2fads.o
 obj-$(CONFIG_EP8248E) += ep8248e.o
+obj-$(CONFIG_MGCOGE) += mgcoge.o
diff --git a/arch/powerpc/platforms/82xx/mgcoge.c b/arch/powerpc/platforms/82xx/mgcoge.c
new file mode 100644 (file)
index 0000000..c2af169
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Keymile mgcoge support
+ * Copyright 2008 DENX Software Engineering GmbH
+ * Author: Heiko Schocher <hs@denx.de>
+ *
+ * based on code from:
+ * Copyright 2007 Freescale Semiconductor, Inc.
+ * Author: Scott Wood <scottwood@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 the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fsl_devices.h>
+#include <linux/of_platform.h>
+
+#include <asm/io.h>
+#include <asm/cpm2.h>
+#include <asm/udbg.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/mpc8260.h>
+#include <asm/prom.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/cpm2_pic.h>
+
+#include "pq2.h"
+
+static void __init mgcoge_pic_init(void)
+{
+       struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic");
+       if (!np) {
+               printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
+               return;
+       }
+
+       cpm2_pic_init(np);
+       of_node_put(np);
+}
+
+struct cpm_pin {
+       int port, pin, flags;
+};
+
+static __initdata struct cpm_pin mgcoge_pins[] = {
+
+       /* SMC2 */
+       {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {1, 9, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+
+       /* SCC4 */
+       {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {3, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {3,  9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {3,  8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {4, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {4, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+};
+
+static void __init init_ioports(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(mgcoge_pins); i++) {
+               const struct cpm_pin *pin = &mgcoge_pins[i];
+               cpm2_set_pin(pin->port - 1, pin->pin, pin->flags);
+       }
+
+       cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8);
+       cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK7, CPM_CLK_RX);
+       cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK8, CPM_CLK_TX);
+}
+
+static void __init mgcoge_setup_arch(void)
+{
+       if (ppc_md.progress)
+               ppc_md.progress("mgcoge_setup_arch()", 0);
+
+       cpm2_reset();
+
+       /* When this is set, snooping CPM DMA from RAM causes
+        * machine checks.  See erratum SIU18.
+        */
+       clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
+
+       init_ioports();
+
+       if (ppc_md.progress)
+               ppc_md.progress("mgcoge_setup_arch(), finish", 0);
+}
+
+static  __initdata struct of_device_id of_bus_ids[] = {
+       { .compatible = "simple-bus", },
+       {},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+       of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+       return 0;
+}
+machine_device_initcall(mgcoge, declare_of_platform_devices);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mgcoge_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+       return of_flat_dt_is_compatible(root, "keymile,mgcoge");
+}
+
+define_machine(mgcoge)
+{
+       .name = "Keymile MGCOGE",
+       .probe = mgcoge_probe,
+       .setup_arch = mgcoge_setup_arch,
+       .init_IRQ = mgcoge_pic_init,
+       .get_irq = cpm2_get_irq,
+       .calibrate_decr = generic_calibrate_decr,
+       .restart = pq2_restart,
+       .progress = udbg_progress,
+};
index 6159c5d4e5f1335d2fd3e7f44dbe887885dab183..83c664afc897c76023d65e7e4b231e9fa26c0310 100644 (file)
@@ -19,7 +19,6 @@ config MPC831x_RDB
 config MPC832x_MDS
        bool "Freescale MPC832x MDS"
        select DEFAULT_UIMAGE
-       select QUICC_ENGINE
        select PPC_MPC832x
        help
          This option enables support for the MPC832x MDS evaluation board.
@@ -27,7 +26,6 @@ config MPC832x_MDS
 config MPC832x_RDB
        bool "Freescale MPC832x RDB"
        select DEFAULT_UIMAGE
-       select QUICC_ENGINE
        select PPC_MPC832x
        help
          This option enables support for the MPC8323 RDB board.
@@ -57,15 +55,12 @@ config MPC834x_ITX
 config MPC836x_MDS
        bool "Freescale MPC836x MDS"
        select DEFAULT_UIMAGE
-       select QUICC_ENGINE
        help
          This option enables support for the MPC836x MDS Processor Board.
 
 config MPC836x_RDK
        bool "Freescale/Logic MPC836x RDK"
        select DEFAULT_UIMAGE
-       select QUICC_ENGINE
-       select QE_GPIO
        select FSL_GTM
        select FSL_LBC
        help
index be62de23beadc1748a3d391c51578ddb74c0a4fc..8bb13c807142c9155940da690e26cdc6b8de48cc 100644 (file)
@@ -85,8 +85,14 @@ static void __init mpc837x_mds_setup_arch(void)
                ppc_md.progress("mpc837x_mds_setup_arch()", 0);
 
 #ifdef CONFIG_PCI
-       for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
+       for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") {
+               if (!of_device_is_available(np)) {
+                       pr_warning("%s: disabled by the firmware.\n",
+                                  np->full_name);
+                       continue;
+               }
                mpc83xx_add_bridge(np);
+       }
 #endif
        mpc837xmds_usb_cfg();
 }
index 291675b0097a902d620b9f203857d925ce919127..b79dc710ed346483d8201a68984fe06cfecb6dbe 100644 (file)
@@ -33,7 +33,6 @@ config MPC85xx_CDS
 config MPC85xx_MDS
        bool "Freescale MPC85xx MDS"
        select DEFAULT_UIMAGE
-       select QUICC_ENGINE
        select PHYLIB
        help
          This option enables support for the MPC85xx MDS board
index d17807a6b89a141b555a7d31781093239249ec26..0293e3d3580f4bd950835cd18ce0f08455a58644 100644 (file)
@@ -213,7 +213,6 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
        svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
-       seq_printf(m, "Machine\t\t: mpc85xx\n");
        seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
 
index 6509ade71668e658729ddb6266217c6ccd8538fe..0c9a856f66b6f7e2c4c918574e958e804d37292d 100644 (file)
@@ -156,7 +156,7 @@ static void __init init_ioports(void)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) {
-               struct cpm_pin *pin = &sbc8560_pins[i];
+               const struct cpm_pin *pin = &sbc8560_pins[i];
                cpm2_set_pin(pin->port, pin->pin, pin->flags);
        }
 
@@ -200,7 +200,6 @@ static void sbc8560_show_cpuinfo(struct seq_file *m)
        svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: Wind River\n");
-       seq_printf(m, "Machine\t\t: SBC8560\n");
        seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
 
index 9355a52694314573d9960ccb292ef42d22b7e704..77dd797a2580e73f90dce98b08a20d1ed5313b75 100644 (file)
@@ -31,6 +31,13 @@ config MPC8610_HPCD
        help
          This option enables support for the MPC8610 HPCD board.
 
+config GEF_SBC610
+       bool "GE Fanuc SBC610"
+       select DEFAULT_UIMAGE
+       select HAS_RAPIDIO
+       help
+         This option enables support for GE Fanuc's SBC610.
+
 endif
 
 config MPC8641
@@ -39,7 +46,7 @@ config MPC8641
        select FSL_PCI if PCI
        select PPC_UDBG_16550
        select MPIC
-       default y if MPC8641_HPCN || SBC8641D
+       default y if MPC8641_HPCN || SBC8641D || GEF_SBC610
 
 config MPC8610
        bool
index 8fee37dec79517ffb344f20398e34361df748e34..4a56ff619afdee7fc649c4e17203d73104f6d521 100644 (file)
@@ -7,3 +7,4 @@ obj-$(CONFIG_SMP)               += mpc86xx_smp.o
 obj-$(CONFIG_MPC8641_HPCN)     += mpc86xx_hpcn.o
 obj-$(CONFIG_SBC8641D)         += sbc8641d.o
 obj-$(CONFIG_MPC8610_HPCD)     += mpc8610_hpcd.o
+obj-$(CONFIG_GEF_SBC610)       += gef_sbc610.o gef_pic.o
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
new file mode 100644 (file)
index 0000000..50d0a2b
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Interrupt handling for GE Fanuc's FPGA based PIC
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * 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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/irq.h>
+
+#include "gef_pic.h"
+
+#define DEBUG
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while (0)
+#else
+#define DBG(fmt...) do { } while (0)
+#endif
+
+#define GEF_PIC_NUM_IRQS       32
+
+/* Interrupt Controller Interface Registers */
+#define GEF_PIC_INTR_STATUS    0x0000
+
+#define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu))
+#define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0)
+#define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1)
+
+#define GEF_PIC_MCP_MASK(cpu)  (0x0018 + (0x4 * cpu))
+#define GEF_PIC_CPU0_MCP_MASK  GEF_PIC_MCP_MASK(0)
+#define GEF_PIC_CPU1_MCP_MASK  GEF_PIC_MCP_MASK(1)
+
+#define gef_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
+
+
+static DEFINE_SPINLOCK(gef_pic_lock);
+
+static void __iomem *gef_pic_irq_reg_base;
+static struct irq_host *gef_pic_irq_host;
+static int gef_pic_cascade_irq;
+
+/*
+ * Interrupt Controller Handling
+ *
+ * The interrupt controller handles interrupts for most on board interrupts,
+ * apart from PCI interrupts. For example on SBC610:
+ *
+ * 17:31 RO Reserved
+ * 16    RO PCI Express Doorbell 3 Status
+ * 15    RO PCI Express Doorbell 2 Status
+ * 14    RO PCI Express Doorbell 1 Status
+ * 13    RO PCI Express Doorbell 0 Status
+ * 12    RO Real Time Clock Interrupt Status
+ * 11    RO Temperature Interrupt Status
+ * 10    RO Temperature Critical Interrupt Status
+ * 9     RO Ethernet PHY1 Interrupt Status
+ * 8     RO Ethernet PHY3 Interrupt Status
+ * 7     RO PEX8548 Interrupt Status
+ * 6     RO Reserved
+ * 5     RO Watchdog 0 Interrupt Status
+ * 4     RO Watchdog 1 Interrupt Status
+ * 3     RO AXIS Message FIFO A Interrupt Status
+ * 2     RO AXIS Message FIFO B Interrupt Status
+ * 1     RO AXIS Message FIFO C Interrupt Status
+ * 0     RO AXIS Message FIFO D Interrupt Status
+ *
+ * Interrupts can be forwarded to one of two output lines. Nothing
+ * clever is done, so if the masks are incorrectly set, a single input
+ * interrupt could generate interrupts on both output lines!
+ *
+ * The dual lines are there to allow the chained interrupts to be easily
+ * passed into two different cores. We currently do not use this functionality
+ * in this driver.
+ *
+ * Controller can also be configured to generate Machine checks (MCP), again on
+ * two lines, to be attached to two different cores. It is suggested that these
+ * should be masked out.
+ */
+
+void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned int cascade_irq;
+
+       /*
+        * See if we actually have an interrupt, call generic handling code if
+        * we do.
+        */
+       cascade_irq = gef_pic_get_irq();
+
+       if (cascade_irq != NO_IRQ)
+               generic_handle_irq(cascade_irq);
+
+       desc->chip->eoi(irq);
+
+}
+
+static void gef_pic_mask(unsigned int virq)
+{
+       unsigned long flags;
+       unsigned int hwirq;
+       u32 mask;
+
+       hwirq = gef_irq_to_hw(virq);
+
+       spin_lock_irqsave(&gef_pic_lock, flags);
+       mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
+       mask &= ~(1 << hwirq);
+       out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
+       spin_unlock_irqrestore(&gef_pic_lock, flags);
+}
+
+static void gef_pic_mask_ack(unsigned int virq)
+{
+       /* Don't think we actually have to do anything to ack an interrupt,
+        * we just need to clear down the devices interrupt and it will go away
+        */
+       gef_pic_mask(virq);
+}
+
+static void gef_pic_unmask(unsigned int virq)
+{
+       unsigned long flags;
+       unsigned int hwirq;
+       u32 mask;
+
+       hwirq = gef_irq_to_hw(virq);
+
+       spin_lock_irqsave(&gef_pic_lock, flags);
+       mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
+       mask |= (1 << hwirq);
+       out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
+       spin_unlock_irqrestore(&gef_pic_lock, flags);
+}
+
+static struct irq_chip gef_pic_chip = {
+       .typename       = "gefp",
+       .mask           = gef_pic_mask,
+       .mask_ack       = gef_pic_mask_ack,
+       .unmask         = gef_pic_unmask,
+};
+
+
+/* When an interrupt is being configured, this call allows some flexibilty
+ * in deciding which irq_chip structure is used
+ */
+static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
+                         irq_hw_number_t hwirq)
+{
+       /* All interrupts are LEVEL sensitive */
+       get_irq_desc(virq)->status |= IRQ_LEVEL;
+       set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
+
+       return 0;
+}
+
+static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+                           u32 *intspec, unsigned int intsize,
+                           irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+
+       *out_hwirq = intspec[0];
+       if (intsize > 1)
+               *out_flags = intspec[1];
+       else
+               *out_flags = IRQ_TYPE_LEVEL_HIGH;
+
+       return 0;
+}
+
+static struct irq_host_ops gef_pic_host_ops = {
+       .map    = gef_pic_host_map,
+       .xlate  = gef_pic_host_xlate,
+};
+
+
+/*
+ * Initialisation of PIC, this should be called in BSP
+ */
+void __init gef_pic_init(struct device_node *np)
+{
+       unsigned long flags;
+
+       /* Map the devices registers into memory */
+       gef_pic_irq_reg_base = of_iomap(np, 0);
+
+       spin_lock_irqsave(&gef_pic_lock, flags);
+
+       /* Initialise everything as masked. */
+       out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0);
+       out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0);
+
+       out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0);
+       out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0);
+
+       spin_unlock_irqrestore(&gef_pic_lock, flags);
+
+       /* Map controller */
+       gef_pic_cascade_irq = irq_of_parse_and_map(np, 0);
+       if (gef_pic_cascade_irq == NO_IRQ) {
+               printk(KERN_ERR "SBC610: failed to map cascade interrupt");
+               return;
+       }
+
+       /* Setup an irq_host structure */
+       gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
+                                         GEF_PIC_NUM_IRQS,
+                                         &gef_pic_host_ops, NO_IRQ);
+       if (gef_pic_irq_host == NULL)
+               return;
+
+       /* Chain with parent controller */
+       set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade);
+}
+
+/*
+ * This is called when we receive an interrupt with apparently comes from this
+ * chip - check, returning the highest interrupt generated or return NO_IRQ
+ */
+unsigned int gef_pic_get_irq(void)
+{
+       u32 cause, mask, active;
+       unsigned int virq = NO_IRQ;
+       int hwirq;
+
+       cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS);
+
+       mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
+
+       active = cause & mask;
+
+       if (active) {
+               for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--) {
+                       if (active & (0x1 << hwirq))
+                               break;
+               }
+               virq = irq_linear_revmap(gef_pic_irq_host,
+                       (irq_hw_number_t)hwirq);
+       }
+
+       return virq;
+}
+
diff --git a/arch/powerpc/platforms/86xx/gef_pic.h b/arch/powerpc/platforms/86xx/gef_pic.h
new file mode 100644 (file)
index 0000000..6149916
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __GEF_PIC_H__
+#define __GEF_PIC_H__
+
+#include <linux/init.h>
+
+void gef_pic_cascade(unsigned int, struct irq_desc *);
+unsigned int gef_pic_get_irq(void);
+void gef_pic_init(struct device_node *);
+
+#endif /* __GEF_PIC_H__ */
+
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
new file mode 100644 (file)
index 0000000..821c45f
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * GE Fanuc SBC610 board support
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc86xx.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_pci.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+#include "gef_pic.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG (fmt...) do { printk(KERN_ERR "SBC610: " fmt); } while (0)
+#else
+#define DBG (fmt...) do { } while (0)
+#endif
+
+void __iomem *sbc610_regs;
+
+static void __init gef_sbc610_init_irq(void)
+{
+       struct device_node *cascade_node = NULL;
+
+       mpc86xx_init_irq();
+
+       /*
+        * There is a simple interrupt handler in the main FPGA, this needs
+        * to be cascaded into the MPIC
+        */
+       cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic");
+       if (!cascade_node) {
+               printk(KERN_WARNING "SBC610: No FPGA PIC\n");
+               return;
+       }
+
+       gef_pic_init(cascade_node);
+       of_node_put(cascade_node);
+}
+
+static void __init gef_sbc610_setup_arch(void)
+{
+       struct device_node *regs;
+#ifdef CONFIG_PCI
+       struct device_node *np;
+
+       for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
+               fsl_add_bridge(np, 1);
+       }
+#endif
+
+       printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n");
+
+#ifdef CONFIG_SMP
+       mpc86xx_smp_init();
+#endif
+
+       /* Remap basic board registers */
+       regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
+       if (regs) {
+               sbc610_regs = of_iomap(regs, 0);
+               if (sbc610_regs == NULL)
+                       printk(KERN_WARNING "Unable to map board registers\n");
+               of_node_put(regs);
+       }
+}
+
+/* Return the PCB revision */
+static unsigned int gef_sbc610_get_pcb_rev(void)
+{
+       unsigned int reg;
+
+       reg = ioread32(sbc610_regs);
+       return (reg >> 8) & 0xff;
+}
+
+/* Return the board (software) revision */
+static unsigned int gef_sbc610_get_board_rev(void)
+{
+       unsigned int reg;
+
+       reg = ioread32(sbc610_regs);
+       return (reg >> 16) & 0xff;
+}
+
+/* Return the FPGA revision */
+static unsigned int gef_sbc610_get_fpga_rev(void)
+{
+       unsigned int reg;
+
+       reg = ioread32(sbc610_regs);
+       return (reg >> 24) & 0xf;
+}
+
+static void gef_sbc610_show_cpuinfo(struct seq_file *m)
+{
+       uint memsize = total_memory;
+       uint svid = mfspr(SPRN_SVR);
+
+       seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+
+       seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(),
+               ('A' + gef_sbc610_get_board_rev() - 1));
+       seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev());
+
+       seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+}
+
+static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev)
+{
+       unsigned int val;
+
+       printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
+
+       /* Ensure ports 1, 2, 3, 4 & 5 are enabled */
+       pci_read_config_dword(pdev, 0xe0, &val);
+       pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5);
+
+       /* System clock is 48-MHz Oscillator and EHCI Enabled. */
+       pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+       gef_sbc610_nec_fixup);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+ * board. It is expected thati, in the future, a kernel may support multiple
+ * boards.
+ */
+static int __init gef_sbc610_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       if (of_flat_dt_is_compatible(root, "gef,sbc610"))
+               return 1;
+
+       return 0;
+}
+
+static long __init mpc86xx_time_init(void)
+{
+       unsigned int temp;
+
+       /* Set the time base to zero */
+       mtspr(SPRN_TBWL, 0);
+       mtspr(SPRN_TBWU, 0);
+
+       temp = mfspr(SPRN_HID0);
+       temp |= HID0_TBEN;
+       mtspr(SPRN_HID0, temp);
+       asm volatile("isync");
+
+       return 0;
+}
+
+static __initdata struct of_device_id of_bus_ids[] = {
+       { .compatible = "simple-bus", },
+       {},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+       printk(KERN_DEBUG "Probe platform devices\n");
+       of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+       return 0;
+}
+machine_device_initcall(gef_sbc610, declare_of_platform_devices);
+
+define_machine(gef_sbc610) {
+       .name                   = "GE Fanuc SBC610",
+       .probe                  = gef_sbc610_probe,
+       .setup_arch             = gef_sbc610_setup_arch,
+       .init_IRQ               = gef_sbc610_init_irq,
+       .show_cpuinfo           = gef_sbc610_show_cpuinfo,
+       .get_irq                = mpic_get_irq,
+       .restart                = fsl_rstcr_restart,
+       .time_init              = mpc86xx_time_init,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = udbg_progress,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+};
index 5eedb710896e7568b8fc29cb1c78b1f7f5def81b..e8d54ac5292c3ec972497fc1ee1b4178915e0345 100644 (file)
@@ -238,7 +238,6 @@ static void __init mpc86xx_hpcd_setup_arch(void)
         }
 #endif
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-       preallocate_diu_videomemory();
        diu_ops.get_pixel_format        = mpc8610hpcd_get_pixel_format;
        diu_ops.set_gamma_table         = mpc8610hpcd_set_gamma_table;
        diu_ops.set_monitor_port        = mpc8610hpcd_set_monitor_port;
index f712d9c0991be7ef9c6c0cc3cdccec2e98e1094e..2672829a71dc400397d3adefc84cb5dcbc15ffd5 100644 (file)
@@ -101,19 +101,11 @@ mpc86xx_hpcn_setup_arch(void)
 static void
 mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
 {
-       struct device_node *root;
        uint memsize = total_memory;
-       const char *model = "";
        uint svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
 
-       root = of_find_node_by_path("/");
-       if (root)
-               model = of_get_property(root, "model", NULL);
-       seq_printf(m, "Machine\t\t: %s\n", model);
-       of_node_put(root);
-
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
        seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
index 00e6fad3b3ca99f155350617d8838f33abe1069a..da677a74e2d110068ca8608cc064645be0625e88 100644 (file)
@@ -63,19 +63,11 @@ sbc8641_setup_arch(void)
 static void
 sbc8641_show_cpuinfo(struct seq_file *m)
 {
-       struct device_node *root;
        uint memsize = total_memory;
-       const char *model = "";
        uint svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: Wind River Systems\n");
 
-       root = of_find_node_by_path("/");
-       if (root)
-               model = of_get_property(root, "model", NULL);
-       seq_printf(m, "Machine\t\t: %s\n", model);
-       of_node_put(root);
-
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
        seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
index 71d7562e190be1120090b04d1ac547173812af73..48a920a98e7bff033c07070f3d68f1ec8ccafcc7 100644 (file)
@@ -49,6 +49,12 @@ config PPC_ADDER875
          This enables support for the Analogue & Micro Adder 875
          board.
 
+config PPC_MGSUVD
+       bool "MGSUVD"
+       select CPM1
+       help
+         This enables support for the Keymile MGSUVD board.
+
 endchoice
 
 menu "Freescale Ethernet driver platform-specific options"
index 7b71d9c8fb457e1e59444553572f61c83d50164d..bdbfd74960188ae6c39b2fd0c057a3b061154f4a 100644 (file)
@@ -6,3 +6,4 @@ obj-$(CONFIG_MPC885ADS)   += mpc885ads_setup.o
 obj-$(CONFIG_MPC86XADS)   += mpc86xads_setup.o
 obj-$(CONFIG_PPC_EP88XC)  += ep88xc.o
 obj-$(CONFIG_PPC_ADDER875) += adder875.o
+obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o
diff --git a/arch/powerpc/platforms/8xx/mgsuvd.c b/arch/powerpc/platforms/8xx/mgsuvd.c
new file mode 100644 (file)
index 0000000..ca3cb07
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *
+ * Platform setup for the Keymile mgsuvd board
+ *
+ * Heiko Schocher <hs@denx.de>
+ *
+ * Copyright 2008 DENX Software Engineering GmbH
+ *
+ * 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/ioport.h>
+#include <linux/of_platform.h>
+
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/processor.h>
+#include <asm/cpm1.h>
+#include <asm/prom.h>
+#include <asm/fs_pd.h>
+
+#include "mpc8xx.h"
+
+struct cpm_pin {
+       int port, pin, flags;
+};
+
+static __initdata struct cpm_pin mgsuvd_pins[] = {
+       /* SMC1 */
+       {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
+       {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
+
+       /* SCC3 */
+       {CPM_PORTA, 10, CPM_PIN_INPUT},
+       {CPM_PORTA, 11, CPM_PIN_INPUT},
+       {CPM_PORTA, 3, CPM_PIN_INPUT},
+       {CPM_PORTA, 2, CPM_PIN_INPUT},
+       {CPM_PORTC, 13, CPM_PIN_INPUT},
+};
+
+static void __init init_ioports(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(mgsuvd_pins); i++) {
+               struct cpm_pin *pin = &mgsuvd_pins[i];
+               cpm1_set_pin(pin->port, pin->pin, pin->flags);
+       }
+
+       setbits16(&mpc8xx_immr->im_ioport.iop_pcso, 0x300);
+       cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RX);
+       cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_TX);
+       cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
+}
+
+static void __init mgsuvd_setup_arch(void)
+{
+       cpm_reset();
+       init_ioports();
+}
+
+static __initdata struct of_device_id of_bus_ids[] = {
+       { .compatible = "simple-bus" },
+       {},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+       of_platform_bus_probe(NULL, of_bus_ids, NULL);
+       return 0;
+}
+machine_device_initcall(mgsuvd, declare_of_platform_devices);
+
+static int __init mgsuvd_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+       return of_flat_dt_is_compatible(root, "keymile,mgsuvd");
+}
+
+define_machine(mgsuvd) {
+       .name           = "MGSUVD",
+       .probe          = mgsuvd_probe,
+       .setup_arch     = mgsuvd_setup_arch,
+       .init_IRQ       = mpc8xx_pics_init,
+       .get_irq        = mpc8xx_get_irq,
+       .restart        = mpc8xx_restart,
+       .calibrate_decr = mpc8xx_calibrate_decr,
+       .set_rtc_time   = mpc8xx_set_rtc_time,
+       .get_rtc_time   = mpc8xx_get_rtc_time,
+};
index 4c900efa164e43fcd4331bddc81b925e35ad77c8..47e956c871fe8cfc3aea613e5a1552771eccb9b4 100644 (file)
@@ -239,7 +239,8 @@ config TAU_AVERAGE
          If in doubt, say N here.
 
 config QUICC_ENGINE
-       bool
+       bool "Freescale QUICC Engine (QE) Support"
+       depends on FSL_SOC
        select PPC_LIB_RHEAP
        select CRC32
        help
@@ -248,6 +249,15 @@ config QUICC_ENGINE
          Selecting this option means that you wish to build a kernel
          for a machine with a QE coprocessor.
 
+config QE_GPIO
+       bool "QE GPIO support"
+       depends on QUICC_ENGINE
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         Say Y here if you're going to use hardware that connects to the
+         QE GPIOs.
+
 config CPM2
        bool "Enable support for the CPM2 (Communications Processor Module)"
        depends on MPC85xx || 8260
@@ -293,4 +303,13 @@ config OF_RTC
 
 source "arch/powerpc/sysdev/bestcomm/Kconfig"
 
+config MPC8xxx_GPIO
+       bool "MPC8xxx GPIO support"
+       depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || PPC_85xx || PPC_86xx
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         Say Y here if you're going to use hardware that connects to the
+         MPC831x/834x/837x/8572/8610 GPIOs.
+
 endmenu
index be852fd407a85406c4f41594146b49eeb2a13c37..548efa55c8fe590b4b10674488a709563e51108f 100644 (file)
@@ -50,6 +50,7 @@ config 44x
        select PPC_UDBG_16550
        select 4xx_SOC
        select PPC_PCI_CHOICE
+       select PHYS_64BIT
 
 config E200
        bool "Freescale e200"
@@ -128,17 +129,19 @@ config FSL_EMB_PERFMON
 
 config PTE_64BIT
        bool
-       depends on 44x || E500
-       default y if 44x
-       default y if E500 && PHYS_64BIT
+       depends on 44x || E500 || PPC_86xx
+       default y if PHYS_64BIT
 
 config PHYS_64BIT
-       bool 'Large physical address support' if E500
-       depends on 44x || E500
-       default y if 44x
+       bool 'Large physical address support' if E500 || PPC_86xx
+       depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx
        ---help---
          This option enables kernel support for larger than 32-bit physical
-         addresses.  This features is not be available on all e500 cores.
+         addresses.  This feature may not be available on all cores.
+
+         If you have more than 3.5GB of RAM or so, you also need to enable
+         SWIOTLB under Kernel Options for this to work.  The actual number
+         is platform-dependent.
 
          If in doubt, say N here.
 
index e06420af5fe9116cd007645594ee6cd0a962a6ea..ef92e71462151efc9e97c26c0c7442ad7a8c4caf 100644 (file)
@@ -556,11 +556,11 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
         * node's iommu. We -might- do something smarter later though it may
         * never be necessary
         */
-       iommu = cell_iommu_for_node(archdata->numa_node);
+       iommu = cell_iommu_for_node(dev_to_node(dev));
        if (iommu == NULL || list_empty(&iommu->windows)) {
                printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
                       archdata->of_node ? archdata->of_node->full_name : "?",
-                      archdata->numa_node);
+                      dev_to_node(dev));
                return NULL;
        }
        window = list_entry(iommu->windows.next, struct iommu_window, list);
@@ -577,7 +577,7 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
                return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
                                            size, dma_handle,
                                            device_to_mask(dev), flag,
-                                           dev->archdata.numa_node);
+                                           dev_to_node(dev));
        else
                return dma_direct_ops.alloc_coherent(dev, size, dma_handle,
                                                     flag);
index 2c8b8091250f0804f52346ca31b2a27c7ecc6057..cb85d237e492b7156745acc396f308fd99068a34 100644 (file)
@@ -298,8 +298,8 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
 
        d_instantiate(dentry, inode);
        dget(dentry);
-       dir->i_nlink++;
-       dentry->d_inode->i_nlink++;
+       inc_nlink(dir);
+       inc_nlink(dentry->d_inode);
        goto out;
 
 out_free_ctx:
@@ -496,6 +496,8 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
        ret = spufs_context_open(dget(dentry), mntget(mnt));
        if (ret < 0) {
                WARN_ON(spufs_rmdir(inode, dentry));
+               if (affinity)
+                       mutex_unlock(&gang->aff_mutex);
                mutex_unlock(&inode->i_mutex);
                spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
                goto out;
@@ -538,8 +540,8 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
        inode->i_fop = &simple_dir_operations;
 
        d_instantiate(dentry, inode);
-       dir->i_nlink++;
-       dentry->d_inode->i_nlink++;
+       inc_nlink(dir);
+       inc_nlink(dentry->d_inode);
        return ret;
 
 out_iput:
@@ -755,6 +757,7 @@ spufs_create_root(struct super_block *sb, void *data)
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
        SPUFS_I(inode)->i_ctx = NULL;
+       inc_nlink(inode);
 
        ret = -EINVAL;
        if (!spufs_parse_options(sb, data, inode))
index 768c262b936891eeaebb361a1c2612e8ef429588..d3cde6b9d2df68046eaa41512676ed50fea78c66 100644 (file)
@@ -260,13 +260,13 @@ chrp_find_bridges(void)
                                dev->full_name);
                        continue;
                }
-               hose->first_busno = bus_range[0];
+               hose->first_busno = hose->self_busno = bus_range[0];
                hose->last_busno = bus_range[1];
 
                model = of_get_property(dev, "model", NULL);
                if (model == NULL)
                        model = "<none>";
-               if (of_device_is_compatible(dev, "IBM,python")) {
+               if (strncmp(model, "IBM, Python", 11) == 0) {
                        setup_python(hose, dev);
                } else if (is_mot
                           || strncmp(model, "Motorola, Grackle", 17) == 0) {
index 96d1e4b3c493f8628049891f8f54d1813e8cadaa..054dfe5b8e77f39c27d88c70ebcd4295d642bcd0 100644 (file)
@@ -94,12 +94,12 @@ int chrp_set_rtc_time(struct rtc_time *tmarg)
        chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
 
        if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BIN_TO_BCD(tm.tm_sec);
-               BIN_TO_BCD(tm.tm_min);
-               BIN_TO_BCD(tm.tm_hour);
-               BIN_TO_BCD(tm.tm_mon);
-               BIN_TO_BCD(tm.tm_mday);
-               BIN_TO_BCD(tm.tm_year);
+               tm.tm_sec = bin2bcd(tm.tm_sec);
+               tm.tm_min = bin2bcd(tm.tm_min);
+               tm.tm_hour = bin2bcd(tm.tm_hour);
+               tm.tm_mon = bin2bcd(tm.tm_mon);
+               tm.tm_mday = bin2bcd(tm.tm_mday);
+               tm.tm_year = bin2bcd(tm.tm_year);
        }
        chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
        chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
@@ -136,12 +136,12 @@ void chrp_get_rtc_time(struct rtc_time *tm)
        } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
 
        if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BCD_TO_BIN(sec);
-               BCD_TO_BIN(min);
-               BCD_TO_BIN(hour);
-               BCD_TO_BIN(day);
-               BCD_TO_BIN(mon);
-               BCD_TO_BIN(year);
+               sec = bcd2bin(sec);
+               min = bcd2bin(min);
+               hour = bcd2bin(hour);
+               day = bcd2bin(day);
+               mon = bcd2bin(mon);
+               year = bcd2bin(year);
        }
        if (year < 70)
                year += 100;
index 84e2d78b9a627020848a9b1c8264b8a06d0c4b47..7a2ba39d7811a101b1fa14439e087a67b85e2e29 100644 (file)
@@ -164,7 +164,6 @@ static void __init mpc7448_hpc2_init_IRQ(void)
 void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
 {
        seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
-       seq_printf(m, "machine\t\t: MPC7448hpc2\n");
 }
 
 void mpc7448_hpc2_restart(char *cmd)
index 8ff330d026ca686c462b30e8085ae7d7fd701340..2f581521eb9ba9b2e93707eee069cd18a9e322e1 100644 (file)
 
        .globl system_reset_iSeries
 system_reset_iSeries:
+       bl      .relative_toc
        mfspr   r13,SPRN_SPRG3          /* Get alpaca address */
-       LOAD_REG_IMMEDIATE(r23, alpaca)
+       LOAD_REG_ADDR(r23, alpaca)
        li      r0,ALPACA_SIZE
        sub     r23,r13,r23
        divdu   r23,r23,r0              /* r23 has cpu number */
-       LOAD_REG_IMMEDIATE(r13, paca)
+       LOAD_REG_ADDR(r13, paca)
        mulli   r0,r23,PACA_SIZE
        add     r13,r13,r0
        mtspr   SPRN_SPRG3,r13          /* Save it away for the future */
@@ -60,14 +61,14 @@ system_reset_iSeries:
        mtspr   SPRN_CTRLT,r4
 
 /* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */
-/* In the UP case we'll yeild() later, and we will not access the paca anyway */
+/* In the UP case we'll yield() later, and we will not access the paca anyway */
 #ifdef CONFIG_SMP
 1:
        HMT_LOW
-       LOAD_REG_IMMEDIATE(r23, __secondary_hold_spinloop)
+       LOAD_REG_ADDR(r23, __secondary_hold_spinloop)
        ld      r23,0(r23)
        sync
-       LOAD_REG_IMMEDIATE(r3,current_set)
+       LOAD_REG_ADDR(r3,current_set)
        sldi    r28,r24,3               /* get current_set[cpu#] */
        ldx     r3,r3,r28
        addi    r1,r3,THREAD_SIZE
@@ -90,7 +91,7 @@ system_reset_iSeries:
        lbz     r23,PACAPROCSTART(r13)  /* Test if this processor
                                         * should start */
        sync
-       LOAD_REG_IMMEDIATE(r3,current_set)
+       LOAD_REG_ADDR(r3,current_set)
        sldi    r28,r24,3               /* get current_set[cpu#] */
        ldx     r3,r3,r28
        addi    r1,r3,THREAD_SIZE
@@ -255,8 +256,8 @@ hardware_interrupt_iSeries_masked:
 
 _INIT_STATIC(__start_initialization_iSeries)
        /* Clear out the BSS */
-       LOAD_REG_IMMEDIATE(r11,__bss_stop)
-       LOAD_REG_IMMEDIATE(r8,__bss_start)
+       LOAD_REG_ADDR(r11,__bss_stop)
+       LOAD_REG_ADDR(r8,__bss_start)
        sub     r11,r11,r8              /* bss size                     */
        addi    r11,r11,7               /* round up to an even double word */
        rldicl. r11,r11,61,3            /* shift right by 3             */
@@ -267,15 +268,11 @@ _INIT_STATIC(__start_initialization_iSeries)
 3:     stdu    r0,8(r8)
        bdnz    3b
 4:
-       LOAD_REG_IMMEDIATE(r1,init_thread_union)
+       LOAD_REG_ADDR(r1,init_thread_union)
        addi    r1,r1,THREAD_SIZE
        li      r0,0
        stdu    r0,-STACK_FRAME_OVERHEAD(r1)
 
-       LOAD_REG_IMMEDIATE(r2,__toc_start)
-       addi    r2,r2,0x4000
-       addi    r2,r2,0x4000
-
        bl      .iSeries_early_setup
        bl      .early_setup
 
index 731d7b157749e29547c0a615e66b35e0329ea72d..3689c2413d24d758faf9bd9bda5c41400d1b6b71 100644 (file)
@@ -722,13 +722,13 @@ static int mf_set_rtc(struct rtc_time *tm)
        day = tm->tm_mday;
        mon = tm->tm_mon + 1;
 
-       BIN_TO_BCD(sec);
-       BIN_TO_BCD(min);
-       BIN_TO_BCD(hour);
-       BIN_TO_BCD(mon);
-       BIN_TO_BCD(day);
-       BIN_TO_BCD(y1);
-       BIN_TO_BCD(y2);
+       sec = bin2bcd(sec);
+       min = bin2bcd(min);
+       hour = bin2bcd(hour);
+       mon = bin2bcd(mon);
+       day = bin2bcd(day);
+       y1 = bin2bcd(y1);
+       y2 = bin2bcd(y2);
 
        memset(ce_time, 0, sizeof(ce_time));
        ce_time[3] = 0x41;
@@ -777,12 +777,12 @@ static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
                u8 day = ce_msg[10];
                u8 mon = ce_msg[11];
 
-               BCD_TO_BIN(sec);
-               BCD_TO_BIN(min);
-               BCD_TO_BIN(hour);
-               BCD_TO_BIN(day);
-               BCD_TO_BIN(mon);
-               BCD_TO_BIN(year);
+               sec = bcd2bin(sec);
+               min = bcd2bin(min);
+               hour = bcd2bin(hour);
+               day = bcd2bin(day);
+               mon = bcd2bin(mon);
+               year = bcd2bin(year);
 
                if (year <= 69)
                        year += 100;
index 53bca132fb484d413aa27020a8596f58a9409cf6..eac569dee27cc0d576069ddbd933520121ff681d 100644 (file)
@@ -68,12 +68,12 @@ void maple_get_rtc_time(struct rtc_time *tm)
 
        if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
            || RTC_ALWAYS_BCD) {
-               BCD_TO_BIN(tm->tm_sec);
-               BCD_TO_BIN(tm->tm_min);
-               BCD_TO_BIN(tm->tm_hour);
-               BCD_TO_BIN(tm->tm_mday);
-               BCD_TO_BIN(tm->tm_mon);
-               BCD_TO_BIN(tm->tm_year);
+               tm->tm_sec = bcd2bin(tm->tm_sec);
+               tm->tm_min = bcd2bin(tm->tm_min);
+               tm->tm_hour = bcd2bin(tm->tm_hour);
+               tm->tm_mday = bcd2bin(tm->tm_mday);
+               tm->tm_mon = bcd2bin(tm->tm_mon);
+               tm->tm_year = bcd2bin(tm->tm_year);
          }
        if ((tm->tm_year + 1900) < 1970)
                tm->tm_year += 100;
@@ -104,12 +104,12 @@ int maple_set_rtc_time(struct rtc_time *tm)
        year = tm->tm_year;
 
        if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BIN_TO_BCD(sec);
-               BIN_TO_BCD(min);
-               BIN_TO_BCD(hour);
-               BIN_TO_BCD(mon);
-               BIN_TO_BCD(mday);
-               BIN_TO_BCD(year);
+               sec = bin2bcd(sec);
+               min = bin2bcd(min);
+               hour = bin2bcd(hour);
+               mon = bin2bcd(mon);
+               mday = bin2bcd(mday);
+               year = bin2bcd(year);
        }
        maple_clock_write(sec, RTC_SECONDS);
        maple_clock_write(min, RTC_MINUTES);
index 5169ecc37123c07edd3a3344d37434031923eea9..e6c0040ee79752c9721d5b69fbb29dd057de42ef 100644 (file)
@@ -2677,7 +2677,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
        macio_chips[i].of_node  = node;
        macio_chips[i].type     = type;
        macio_chips[i].base     = base;
-       macio_chips[i].flags    = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
+       macio_chips[i].flags    = MACIO_FLAG_SCCA_ON | MACIO_FLAG_SCCB_ON;
        macio_chips[i].name     = macio_names[type];
        revp = of_get_property(node, "revision-id", NULL);
        if (revp)
index 4ae3d00e0bdd9bc98dde1368cd2abc226e6cf1d9..40f72c2a4699f101dbe90f17abbb2e0d31ab54fd 100644 (file)
@@ -787,7 +787,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
 {
        unsigned int save_vector;
        unsigned long target, flags;
-       unsigned int *vector = (unsigned int *)(KERNELBASE+0x100);
+       unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
 
        if (nr < 0 || nr > 3)
                return;
@@ -801,7 +801,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
        save_vector = *vector;
 
        /* Setup fake reset vector that does
-        *   b __secondary_start_pmac_0 + nr*8 - KERNELBASE
+        *   b __secondary_start_pmac_0 + nr*8
         */
        target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
        patch_branch(vector, target, BRANCH_SET_LINK);
index bbbefd64ab5991f3c30c5e7d34a074a3e224d326..59eb840d8ce20782c7cf5809dc46356e2651244c 100644 (file)
@@ -93,11 +93,14 @@ static void to_rtc_time(unsigned long now, struct rtc_time *tm)
 }
 #endif
 
+#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) || \
+    defined(CONFIG_PMAC_SMU)
 static unsigned long from_rtc_time(struct rtc_time *tm)
 {
        return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
                      tm->tm_hour, tm->tm_min, tm->tm_sec);
 }
+#endif
 
 #ifdef CONFIG_ADB_CUDA
 static unsigned long cuda_get_time(void)
index 280ee88cb0b001c21449c18694d498a9c58e6de0..a789bf58ca8b83bb60b98de3d2641cab5b52705c 100644 (file)
@@ -762,7 +762,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
        };
 
        dev->core.archdata.of_node = NULL;
-       dev->core.archdata.numa_node = 0;
+       set_dev_node(&dev->core, 0);
 
        pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
 
index 38fe32a7cc7007b2c3a24a5ed688db7c1a9d7dd2..5cd4d276162085f43177ac56d7effb162dcdb090 100644 (file)
@@ -121,7 +121,7 @@ static long cmm_alloc_pages(long nr)
                        npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN |
                                                                       __GFP_NORETRY | __GFP_NOMEMALLOC);
                        if (!npa) {
-                               pr_info("%s: Can not allocate new page list\n", __FUNCTION__);
+                               pr_info("%s: Can not allocate new page list\n", __func__);
                                free_page(addr);
                                break;
                        }
@@ -138,7 +138,7 @@ static long cmm_alloc_pages(long nr)
                }
 
                if ((rc = plpar_page_set_loaned(__pa(addr)))) {
-                       pr_err("%s: Can not set page to loaned. rc=%ld\n", __FUNCTION__, rc);
+                       pr_err("%s: Can not set page to loaned. rc=%ld\n", __func__, rc);
                        spin_unlock(&cmm_lock);
                        free_page(addr);
                        break;
index 8c1ca477c52cb9164f93ecb03ac698926fccfe98..0ad56ff7b4a04cdd2c024fd4414a39d0f6ac5196 100644 (file)
@@ -41,7 +41,7 @@ static inline const char * pcid_name (struct pci_dev *pdev)
        return "";
 }
 
-#ifdef DEBUG
+#if 0
 static void print_device_node_tree(struct pci_dn *pdn, int dent)
 {
        int i;
index a1a368dd2d992adb57f4b99942ffdb1e6e55a87b..140d02a5232af273b617a464fa08052438266262 100644 (file)
@@ -21,7 +21,7 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
        struct zone *zone;
        int ret;
 
-       start_pfn = base >> PFN_SECTION_SHIFT;
+       start_pfn = base >> PAGE_SHIFT;
        zone = page_zone(pfn_to_page(start_pfn));
 
        /*
index 7637bd38c7957d77d50d01c5f70a8597f3a4ddad..c591a25b0b0d816d7e3f3c206c205ece673ea871 100644 (file)
@@ -466,11 +466,11 @@ static int do_update_property(char *buf, size_t bufsize)
                else
                        action = PSERIES_DRCONF_MEM_REMOVE;
 
-               blocking_notifier_call_chain(&pSeries_reconfig_chain,
-                                            action, value);
+               rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+                                                 action, value);
        }
 
-       return 0;
+       return rc;
 }
 
 /**
index c9ffd8c225f1a7b1b2e852bf86899bd8d785e3b4..f4e55be2eea948548837177f432e893175960391 100644 (file)
@@ -295,19 +295,29 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf,
        if (!tmp)
                return -ENOMEM;
 
-
        spin_lock_irqsave(&rtasd_log_lock, s);
        /* if it's 0, then we know we got the last one (the one in NVRAM) */
-       if (rtas_log_size == 0 && logging_enabled)
-               nvram_clear_error_log();
-       spin_unlock_irqrestore(&rtasd_log_lock, s);
+       while (rtas_log_size == 0) {
+               if (file->f_flags & O_NONBLOCK) {
+                       spin_unlock_irqrestore(&rtasd_log_lock, s);
+                       error = -EAGAIN;
+                       goto out;
+               }
 
+               if (!logging_enabled) {
+                       spin_unlock_irqrestore(&rtasd_log_lock, s);
+                       error = -ENODATA;
+                       goto out;
+               }
+               nvram_clear_error_log();
 
-       error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
-       if (error)
-               goto out;
+               spin_unlock_irqrestore(&rtasd_log_lock, s);
+               error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
+               if (error)
+                       goto out;
+               spin_lock_irqsave(&rtasd_log_lock, s);
+       }
 
-       spin_lock_irqsave(&rtasd_log_lock, s);
        offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
        memcpy(tmp, &rtas_log_buf[offset], count);
 
index 9d8f8c84ab8900e0d661118addbc551bb2c3714d..e00f96baa38160f3b9e5773e88d5d04ab2da7df7 100644 (file)
@@ -37,7 +37,6 @@
 #include <asm/paca.h>
 #include <asm/time.h>
 #include <asm/machdep.h>
-#include "xics.h"
 #include <asm/cputable.h>
 #include <asm/firmware.h>
 #include <asm/system.h>
@@ -49,6 +48,7 @@
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
+#include "xics.h"
 
 
 /*
@@ -105,36 +105,6 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
 }
 
 #ifdef CONFIG_XICS
-static inline void smp_xics_do_message(int cpu, int msg)
-{
-       set_bit(msg, &xics_ipi_message[cpu].value);
-       mb();
-       xics_cause_IPI(cpu);
-}
-
-static void smp_xics_message_pass(int target, int msg)
-{
-       unsigned int i;
-
-       if (target < NR_CPUS) {
-               smp_xics_do_message(target, msg);
-       } else {
-               for_each_online_cpu(i) {
-                       if (target == MSG_ALL_BUT_SELF
-                           && i == smp_processor_id())
-                               continue;
-                       smp_xics_do_message(i, msg);
-               }
-       }
-}
-
-static int __init smp_xics_probe(void)
-{
-       xics_request_IPIs();
-
-       return cpus_weight(cpu_possible_map);
-}
-
 static void __devinit smp_xics_setup_cpu(int cpu)
 {
        if (cpu != boot_cpuid)
index 0fc830f576f5532870157af81cdaf4c65625b67d..e1904774a70fecd21673f6e899d89251905f91d3 100644 (file)
@@ -9,32 +9,30 @@
  *  2 of the License, or (at your option) any later version.
  */
 
-
 #include <linux/types.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <linux/signal.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
 #include <linux/radix-tree.h>
 #include <linux/cpu.h>
+#include <linux/of.h>
 
 #include <asm/firmware.h>
-#include <asm/prom.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/smp.h>
 #include <asm/rtas.h>
 #include <asm/hvcall.h>
 #include <asm/machdep.h>
-#include <asm/i8259.h>
 
 #include "xics.h"
 #include "plpar_wrappers.h"
 
+static struct irq_host *xics_host;
+
 #define XICS_IPI               2
 #define XICS_IRQ_SPURIOUS      0
 
  */
 #define IPI_PRIORITY           4
 
+static unsigned int default_server = 0xFF;
+static unsigned int default_distrib_server = 0;
+static unsigned int interrupt_server_size = 8;
+
+/* RTAS service tokens */
+static int ibm_get_xive;
+static int ibm_set_xive;
+static int ibm_int_on;
+static int ibm_int_off;
+
+
+/* Direct hardware low level accessors */
+
+/* The part of the interrupt presentation layer that we care about */
 struct xics_ipl {
        union {
                u32 word;
@@ -65,27 +77,6 @@ struct xics_ipl {
 
 static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
 
-static unsigned int default_server = 0xFF;
-static unsigned int default_distrib_server = 0;
-static unsigned int interrupt_server_size = 8;
-
-static struct irq_host *xics_host;
-
-/*
- * XICS only has a single IPI, so encode the messages per CPU
- */
-struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
-
-/* RTAS service tokens */
-static int ibm_get_xive;
-static int ibm_set_xive;
-static int ibm_int_on;
-static int ibm_int_off;
-
-
-/* Direct HW low level accessors */
-
-
 static inline unsigned int direct_xirr_info_get(void)
 {
        int cpu = smp_processor_id();
@@ -93,7 +84,7 @@ static inline unsigned int direct_xirr_info_get(void)
        return in_be32(&xics_per_cpu[cpu]->xirr.word);
 }
 
-static inline void direct_xirr_info_set(int value)
+static inline void direct_xirr_info_set(unsigned int value)
 {
        int cpu = smp_processor_id();
 
@@ -115,7 +106,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
 
 /* LPAR low level accessors */
 
-
 static inline unsigned int lpar_xirr_info_get(void)
 {
        unsigned long lpar_rc;
@@ -127,15 +117,14 @@ static inline unsigned int lpar_xirr_info_get(void)
        return (unsigned int)return_value;
 }
 
-static inline void lpar_xirr_info_set(int value)
+static inline void lpar_xirr_info_set(unsigned int value)
 {
        unsigned long lpar_rc;
-       unsigned long val64 = value & 0xffffffff;
 
-       lpar_rc = plpar_eoi(val64);
+       lpar_rc = plpar_eoi(value);
        if (lpar_rc != H_SUCCESS)
-               panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
-                     val64);
+               panic("bad return code EOI - rc = %ld, value=%x\n", lpar_rc,
+                     value);
 }
 
 static inline void lpar_cppr_info(u8 value)
@@ -157,48 +146,7 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
 }
 
 
-/* High level handlers and init code */
-
-static void xics_update_irq_servers(void)
-{
-       int i, j;
-       struct device_node *np;
-       u32 ilen;
-       const u32 *ireg, *isize;
-       u32 hcpuid;
-
-       /* Find the server numbers for the boot cpu. */
-       np = of_get_cpu_node(boot_cpuid, NULL);
-       BUG_ON(!np);
-
-       ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
-       if (!ireg) {
-               of_node_put(np);
-               return;
-       }
-
-       i = ilen / sizeof(int);
-       hcpuid = get_hard_smp_processor_id(boot_cpuid);
-
-       /* Global interrupt distribution server is specified in the last
-        * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
-        * entry fom this property for current boot cpu id and use it as
-        * default distribution server
-        */
-       for (j = 0; j < i; j += 2) {
-               if (ireg[j] == hcpuid) {
-                       default_server = hcpuid;
-                       default_distrib_server = ireg[j+1];
-
-                       isize = of_get_property(np,
-                                       "ibm,interrupt-server#-size", NULL);
-                       if (isize)
-                               interrupt_server_size = *isize;
-               }
-       }
-
-       of_node_put(np);
-}
+/* Interface to generic irq subsystem */
 
 #ifdef CONFIG_SMP
 static int get_irq_server(unsigned int virq, unsigned int strict_check)
@@ -208,9 +156,6 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
        cpumask_t cpumask = irq_desc[virq].affinity;
        cpumask_t tmp = CPU_MASK_NONE;
 
-       if (! cpu_isset(default_server, cpu_online_map))
-               xics_update_irq_servers();
-
        if (!distribute_irqs)
                return default_server;
 
@@ -238,7 +183,6 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
 }
 #endif
 
-
 static void xics_unmask_irq(unsigned int virq)
 {
        unsigned int irq;
@@ -257,21 +201,28 @@ static void xics_unmask_irq(unsigned int virq)
        call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
                                DEFAULT_PRIORITY);
        if (call_status != 0) {
-               printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive "
-                      "returned %d\n", irq, call_status);
-               printk("set_xive %x, server %x\n", ibm_set_xive, server);
+               printk(KERN_ERR
+                       "%s: ibm_set_xive irq %u server %x returned %d\n",
+                       __func__, irq, server, call_status);
                return;
        }
 
        /* Now unmask the interrupt (often a no-op) */
        call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
        if (call_status != 0) {
-               printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on "
-                      "returned %d\n", irq, call_status);
+               printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
+                       __func__, irq, call_status);
                return;
        }
 }
 
+static unsigned int xics_startup(unsigned int virq)
+{
+       /* unmask it */
+       xics_unmask_irq(virq);
+       return 0;
+}
+
 static void xics_mask_real_irq(unsigned int irq)
 {
        int call_status;
@@ -281,8 +232,8 @@ static void xics_mask_real_irq(unsigned int irq)
 
        call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
        if (call_status != 0) {
-               printk(KERN_ERR "xics_disable_real_irq: irq=%u: "
-                      "ibm_int_off returned %d\n", irq, call_status);
+               printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
+                       __func__, irq, call_status);
                return;
        }
 
@@ -290,8 +241,8 @@ static void xics_mask_real_irq(unsigned int irq)
        call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq,
                                default_server, 0xff);
        if (call_status != 0) {
-               printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)"
-                      " returned %d\n", irq, call_status);
+               printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
+                       __func__, irq, call_status);
                return;
        }
 }
@@ -308,132 +259,77 @@ static void xics_mask_irq(unsigned int virq)
        xics_mask_real_irq(irq);
 }
 
-static unsigned int xics_startup(unsigned int virq)
-{
-       unsigned int irq;
-
-       /* force a reverse mapping of the interrupt so it gets in the cache */
-       irq = (unsigned int)irq_map[virq].hwirq;
-       irq_radix_revmap(xics_host, irq);
-
-       /* unmask it */
-       xics_unmask_irq(virq);
-       return 0;
-}
-
-static void xics_eoi_direct(unsigned int virq)
+static void xics_mask_unknown_vec(unsigned int vec)
 {
-       unsigned int irq = (unsigned int)irq_map[virq].hwirq;
-
-       iosync();
-       direct_xirr_info_set((0xff << 24) | irq);
+       printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
+       xics_mask_real_irq(vec);
 }
 
-
-static void xics_eoi_lpar(unsigned int virq)
+static inline unsigned int xics_xirr_vector(unsigned int xirr)
 {
-       unsigned int irq = (unsigned int)irq_map[virq].hwirq;
-
-       iosync();
-       lpar_xirr_info_set((0xff << 24) | irq);
+       /*
+        * The top byte is the old cppr, to be restored on EOI.
+        * The remaining 24 bits are the vector.
+        */
+       return xirr & 0x00ffffff;
 }
 
-static inline unsigned int xics_remap_irq(unsigned int vec)
+static unsigned int xics_get_irq_direct(void)
 {
+       unsigned int xirr = direct_xirr_info_get();
+       unsigned int vec = xics_xirr_vector(xirr);
        unsigned int irq;
 
-       vec &= 0x00ffffff;
-
        if (vec == XICS_IRQ_SPURIOUS)
                return NO_IRQ;
-       irq = irq_radix_revmap(xics_host, vec);
+
+       irq = irq_radix_revmap_lookup(xics_host, vec);
        if (likely(irq != NO_IRQ))
                return irq;
 
-       printk(KERN_ERR "Interrupt %u (real) is invalid,"
-              " disabling it.\n", vec);
-       xics_mask_real_irq(vec);
-       return NO_IRQ;
-}
+       /* We don't have a linux mapping, so have rtas mask it. */
+       xics_mask_unknown_vec(vec);
 
-static unsigned int xics_get_irq_direct(void)
-{
-       return xics_remap_irq(direct_xirr_info_get());
+       /* We might learn about it later, so EOI it */
+       direct_xirr_info_set(xirr);
+       return NO_IRQ;
 }
 
 static unsigned int xics_get_irq_lpar(void)
 {
-       return xics_remap_irq(lpar_xirr_info_get());
-}
-
-#ifdef CONFIG_SMP
-
-static irqreturn_t xics_ipi_dispatch(int cpu)
-{
-       WARN_ON(cpu_is_offline(cpu));
+       unsigned int xirr = lpar_xirr_info_get();
+       unsigned int vec = xics_xirr_vector(xirr);
+       unsigned int irq;
 
-       while (xics_ipi_message[cpu].value) {
-               if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
-                                      &xics_ipi_message[cpu].value)) {
-                       mb();
-                       smp_message_recv(PPC_MSG_CALL_FUNCTION);
-               }
-               if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
-                                      &xics_ipi_message[cpu].value)) {
-                       mb();
-                       smp_message_recv(PPC_MSG_RESCHEDULE);
-               }
-               if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
-                                      &xics_ipi_message[cpu].value)) {
-                       mb();
-                       smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
-               }
-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
-               if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
-                                      &xics_ipi_message[cpu].value)) {
-                       mb();
-                       smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
-               }
-#endif
-       }
-       return IRQ_HANDLED;
-}
+       if (vec == XICS_IRQ_SPURIOUS)
+               return NO_IRQ;
 
-static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id)
-{
-       int cpu = smp_processor_id();
+       irq = irq_radix_revmap_lookup(xics_host, vec);
+       if (likely(irq != NO_IRQ))
+               return irq;
 
-       direct_qirr_info(cpu, 0xff);
+       /* We don't have a linux mapping, so have RTAS mask it. */
+       xics_mask_unknown_vec(vec);
 
-       return xics_ipi_dispatch(cpu);
+       /* We might learn about it later, so EOI it */
+       lpar_xirr_info_set(xirr);
+       return NO_IRQ;
 }
 
-static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id)
+static void xics_eoi_direct(unsigned int virq)
 {
-       int cpu = smp_processor_id();
-
-       lpar_qirr_info(cpu, 0xff);
+       unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
-       return xics_ipi_dispatch(cpu);
+       iosync();
+       direct_xirr_info_set((0xff << 24) | irq);
 }
 
-void xics_cause_IPI(int cpu)
+static void xics_eoi_lpar(unsigned int virq)
 {
-       if (firmware_has_feature(FW_FEATURE_LPAR))
-               lpar_qirr_info(cpu, IPI_PRIORITY);
-       else
-               direct_qirr_info(cpu, IPI_PRIORITY);
-}
-
-#endif /* CONFIG_SMP */
+       unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
-static void xics_set_cpu_priority(unsigned char cppr)
-{
-       if (firmware_has_feature(FW_FEATURE_LPAR))
-               lpar_cppr_info(cppr);
-       else
-               direct_cppr_info(cppr);
        iosync();
+       lpar_xirr_info_set((0xff << 24) | irq);
 }
 
 static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
@@ -450,8 +346,8 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
        status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
 
        if (status) {
-               printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive "
-                      "returns %d\n", irq, status);
+               printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
+                       __func__, irq, status);
                return;
        }
 
@@ -463,8 +359,9 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
        if (irq_server == -1) {
                char cpulist[128];
                cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
-               printk(KERN_WARNING "xics_set_affinity: No online cpus in "
-                               "the mask %s for irq %d\n", cpulist, virq);
+               printk(KERN_WARNING
+                       "%s: No online cpus in the mask %s for irq %d\n",
+                       __func__, cpulist, virq);
                return;
        }
 
@@ -472,28 +369,12 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
                                irq, irq_server, xics_status[1]);
 
        if (status) {
-               printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive "
-                      "returns %d\n", irq, status);
+               printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
+                       __func__, irq, status);
                return;
        }
 }
 
-void xics_setup_cpu(void)
-{
-       xics_set_cpu_priority(0xff);
-
-       /*
-        * Put the calling processor into the GIQ.  This is really only
-        * necessary from a secondary thread as the OF start-cpu interface
-        * performs this function for us on primary threads.
-        *
-        * XXX: undo of teardown on kexec needs this too, as may hotplug
-        */
-       rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
-               (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
-}
-
-
 static struct irq_chip xics_pic_direct = {
        .typename = " XICS     ",
        .startup = xics_startup,
@@ -503,7 +384,6 @@ static struct irq_chip xics_pic_direct = {
        .set_affinity = xics_set_affinity
 };
 
-
 static struct irq_chip xics_pic_lpar = {
        .typename = " XICS     ",
        .startup = xics_startup,
@@ -513,6 +393,9 @@ static struct irq_chip xics_pic_lpar = {
        .set_affinity = xics_set_affinity
 };
 
+
+/* Interface to arch irq controller subsystem layer */
+
 /* Points to the irq_chip we're actually using */
 static struct irq_chip *xics_irq_chip;
 
@@ -530,6 +413,9 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
 {
        pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
 
+       /* Insert the interrupt mapping into the radix tree for fast lookup */
+       irq_radix_revmap_insert(xics_host, virq, hw);
+
        get_irq_desc(virq)->status |= IRQ_LEVEL;
        set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
        return 0;
@@ -569,10 +455,169 @@ static void __init xics_init_host(void)
        irq_set_default_host(xics_host);
 }
 
+
+/* Inter-processor interrupt support */
+
+#ifdef CONFIG_SMP
+/*
+ * XICS only has a single IPI, so encode the messages per CPU
+ */
+struct xics_ipi_struct {
+        unsigned long value;
+       } ____cacheline_aligned;
+
+static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+
+static inline void smp_xics_do_message(int cpu, int msg)
+{
+       set_bit(msg, &xics_ipi_message[cpu].value);
+       mb();
+       if (firmware_has_feature(FW_FEATURE_LPAR))
+               lpar_qirr_info(cpu, IPI_PRIORITY);
+       else
+               direct_qirr_info(cpu, IPI_PRIORITY);
+}
+
+void smp_xics_message_pass(int target, int msg)
+{
+       unsigned int i;
+
+       if (target < NR_CPUS) {
+               smp_xics_do_message(target, msg);
+       } else {
+               for_each_online_cpu(i) {
+                       if (target == MSG_ALL_BUT_SELF
+                           && i == smp_processor_id())
+                               continue;
+                       smp_xics_do_message(i, msg);
+               }
+       }
+}
+
+static irqreturn_t xics_ipi_dispatch(int cpu)
+{
+       WARN_ON(cpu_is_offline(cpu));
+
+       mb();   /* order mmio clearing qirr */
+       while (xics_ipi_message[cpu].value) {
+               if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
+                                      &xics_ipi_message[cpu].value)) {
+                       smp_message_recv(PPC_MSG_CALL_FUNCTION);
+               }
+               if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
+                                      &xics_ipi_message[cpu].value)) {
+                       smp_message_recv(PPC_MSG_RESCHEDULE);
+               }
+               if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
+                                      &xics_ipi_message[cpu].value)) {
+                       smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
+               }
+#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
+               if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
+                                      &xics_ipi_message[cpu].value)) {
+                       smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
+               }
+#endif
+       }
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id)
+{
+       int cpu = smp_processor_id();
+
+       direct_qirr_info(cpu, 0xff);
+
+       return xics_ipi_dispatch(cpu);
+}
+
+static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id)
+{
+       int cpu = smp_processor_id();
+
+       lpar_qirr_info(cpu, 0xff);
+
+       return xics_ipi_dispatch(cpu);
+}
+
+static void xics_request_ipi(void)
+{
+       unsigned int ipi;
+       int rc;
+
+       ipi = irq_create_mapping(xics_host, XICS_IPI);
+       BUG_ON(ipi == NO_IRQ);
+
+       /*
+        * IPIs are marked IRQF_DISABLED as they must run with irqs
+        * disabled
+        */
+       set_irq_handler(ipi, handle_percpu_irq);
+       if (firmware_has_feature(FW_FEATURE_LPAR))
+               rc = request_irq(ipi, xics_ipi_action_lpar,
+                               IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+       else
+               rc = request_irq(ipi, xics_ipi_action_direct,
+                               IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+       BUG_ON(rc);
+}
+
+int __init smp_xics_probe(void)
+{
+       xics_request_ipi();
+
+       return cpus_weight(cpu_possible_map);
+}
+
+#endif /* CONFIG_SMP */
+
+
+/* Initialization */
+
+static void xics_update_irq_servers(void)
+{
+       int i, j;
+       struct device_node *np;
+       u32 ilen;
+       const u32 *ireg, *isize;
+       u32 hcpuid;
+
+       /* Find the server numbers for the boot cpu. */
+       np = of_get_cpu_node(boot_cpuid, NULL);
+       BUG_ON(!np);
+
+       ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
+       if (!ireg) {
+               of_node_put(np);
+               return;
+       }
+
+       i = ilen / sizeof(int);
+       hcpuid = get_hard_smp_processor_id(boot_cpuid);
+
+       /* Global interrupt distribution server is specified in the last
+        * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
+        * entry fom this property for current boot cpu id and use it as
+        * default distribution server
+        */
+       for (j = 0; j < i; j += 2) {
+               if (ireg[j] == hcpuid) {
+                       default_server = hcpuid;
+                       default_distrib_server = ireg[j+1];
+               }
+       }
+
+       /* get the bit size of server numbers */
+       isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
+       if (isize)
+               interrupt_server_size = *isize;
+
+       of_node_put(np);
+}
+
 static void __init xics_map_one_cpu(int hw_id, unsigned long addr,
                                     unsigned long size)
 {
-#ifdef CONFIG_SMP
        int i;
 
        /* This may look gross but it's good enough for now, we don't quite
@@ -586,11 +631,6 @@ static void __init xics_map_one_cpu(int hw_id, unsigned long addr,
                        return;
                }
        }
-#else
-       if (hw_id != 0)
-               return;
-       xics_per_cpu[0] = ioremap(addr, size);
-#endif /* CONFIG_SMP */
 }
 
 static void __init xics_init_one_node(struct device_node *np,
@@ -652,15 +692,17 @@ void __init xics_init_IRQ(void)
 
        for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") {
                found = 1;
-               if (firmware_has_feature(FW_FEATURE_LPAR))
+               if (firmware_has_feature(FW_FEATURE_LPAR)) {
+                       of_node_put(np);
                        break;
+                       }
                xics_init_one_node(np, &indx);
        }
        if (found == 0)
                return;
 
-       xics_init_host();
        xics_update_irq_servers();
+       xics_init_host();
 
        if (firmware_has_feature(FW_FEATURE_LPAR))
                ppc_md.get_irq = xics_get_irq_lpar;
@@ -672,30 +714,31 @@ void __init xics_init_IRQ(void)
        ppc64_boot_msg(0x21, "XICS Done");
 }
 
+/* Cpu startup, shutdown, and hotplug */
 
-#ifdef CONFIG_SMP
-void xics_request_IPIs(void)
+static void xics_set_cpu_priority(unsigned char cppr)
 {
-       unsigned int ipi;
-       int rc;
-
-       ipi = irq_create_mapping(xics_host, XICS_IPI);
-       BUG_ON(ipi == NO_IRQ);
-
-       /*
-        * IPIs are marked IRQF_DISABLED as they must run with irqs
-        * disabled
-        */
-       set_irq_handler(ipi, handle_percpu_irq);
        if (firmware_has_feature(FW_FEATURE_LPAR))
-               rc = request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED,
-                               "IPI", NULL);
+               lpar_cppr_info(cppr);
        else
-               rc = request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED,
-                               "IPI", NULL);
-       BUG_ON(rc);
+               direct_cppr_info(cppr);
+       iosync();
+}
+
+/* Have the calling processor join or leave the specified global queue */
+static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
+{
+       int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
+               (1UL << interrupt_server_size) - 1 - gserver, join);
+       WARN_ON(status < 0);
+}
+
+void xics_setup_cpu(void)
+{
+       xics_set_cpu_priority(0xff);
+
+       xics_set_cpu_giq(default_distrib_server, 1);
 }
-#endif /* CONFIG_SMP */
 
 void xics_teardown_cpu(void)
 {
@@ -703,9 +746,7 @@ void xics_teardown_cpu(void)
 
        xics_set_cpu_priority(0);
 
-       /*
-        * Clear IPI
-        */
+       /* Clear any pending IPI request */
        if (firmware_has_feature(FW_FEATURE_LPAR))
                lpar_qirr_info(cpu, 0xff);
        else
@@ -714,34 +755,28 @@ void xics_teardown_cpu(void)
 
 void xics_kexec_teardown_cpu(int secondary)
 {
-       unsigned int ipi;
-       struct irq_desc *desc;
-
        xics_teardown_cpu();
 
        /*
-        * we need to EOI the IPI
+        * we take the ipi irq but and never return so we
+        * need to EOI the IPI, but want to leave our priority 0
         *
-        * probably need to check all the other interrupts too
+        * should we check all the other interrupts too?
         * should we be flagging idle loop instead?
         * or creating some task to be scheduled?
         */
 
-       ipi = irq_find_mapping(xics_host, XICS_IPI);
-       if (ipi == XICS_IRQ_SPURIOUS)
-               return;
-       desc = get_irq_desc(ipi);
-       if (desc->chip && desc->chip->eoi)
-               desc->chip->eoi(ipi);
+       if (firmware_has_feature(FW_FEATURE_LPAR))
+               lpar_xirr_info_set((0x00 << 24) | XICS_IPI);
+       else
+               direct_xirr_info_set((0x00 << 24) | XICS_IPI);
 
        /*
         * Some machines need to have at least one cpu in the GIQ,
         * so leave the master cpu in the group.
         */
        if (secondary)
-               rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
-                                  (1UL << interrupt_server_size) - 1 -
-                                  default_distrib_server, 0);
+               xics_set_cpu_giq(default_distrib_server, 0);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -749,17 +784,18 @@ void xics_kexec_teardown_cpu(int secondary)
 /* Interrupts are disabled. */
 void xics_migrate_irqs_away(void)
 {
-       int status;
        int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
        unsigned int irq, virq;
 
+       /* If we used to be the default server, move to the new "boot_cpuid" */
+       if (hw_cpu == default_server)
+               xics_update_irq_servers();
+
        /* Reject any interrupt that was queued to us... */
        xics_set_cpu_priority(0);
 
-       /* remove ourselves from the global interrupt queue */
-       status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
-               (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
-       WARN_ON(status < 0);
+       /* Remove ourselves from the global interrupt queue */
+       xics_set_cpu_giq(default_distrib_server, 0);
 
        /* Allow IPIs again... */
        xics_set_cpu_priority(DEFAULT_PRIORITY);
@@ -767,6 +803,7 @@ void xics_migrate_irqs_away(void)
        for_each_irq(virq) {
                struct irq_desc *desc;
                int xics_status[2];
+               int status;
                unsigned long flags;
 
                /* We cant set affinity on ISA interrupts */
@@ -790,9 +827,8 @@ void xics_migrate_irqs_away(void)
 
                status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
                if (status) {
-                       printk(KERN_ERR "migrate_irqs_away: irq=%u "
-                                       "ibm,get-xive returns %d\n",
-                                       virq, status);
+                       printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
+                                       __func__, irq, status);
                        goto unlock;
                }
 
index 1c5321ae8f2f06a507a7ecbdccfd076077c00144..d1d5a83039aeb7928bf9b8849e33e2be6bc605ee 100644 (file)
 #ifndef _POWERPC_KERNEL_XICS_H
 #define _POWERPC_KERNEL_XICS_H
 
-#include <linux/cache.h>
-
 extern void xics_init_IRQ(void);
 extern void xics_setup_cpu(void);
 extern void xics_teardown_cpu(void);
 extern void xics_kexec_teardown_cpu(int secondary);
-extern void xics_cause_IPI(int cpu);
-extern  void xics_request_IPIs(void);
 extern void xics_migrate_irqs_away(void);
-
-struct xics_ipi_struct {
-       volatile unsigned long value;
-} ____cacheline_aligned;
-
-extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+extern int smp_xics_probe(void);
+extern void smp_xics_message_pass(int target, int msg);
 
 #endif /* _POWERPC_KERNEL_XICS_H */
index 72fb35b9ebcadfbe50a72cabf66cad08305b6bc1..396582835cb51bf46dc7ac8623ea29b723a5251b 100644 (file)
@@ -6,3 +6,9 @@ config PPC4xx_PCI_EXPRESS
        bool
        depends on PCI && 4xx
        default n
+
+config PPC_MSI_BITMAP
+       bool
+       depends on PCI_MSI
+       default y if MPIC
+       default y if FSL_PCI
index a90054b56d5c5a8cba8589885566b1eb88c1545b..a44709a94f9734e0b51981a06a32f1550c19194f 100644 (file)
@@ -5,6 +5,7 @@ endif
 mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
 obj-$(CONFIG_MPIC)             += mpic.o $(mpic-msi-obj-y)
 fsl-msi-obj-$(CONFIG_PCI_MSI)  += fsl_msi.o
+obj-$(CONFIG_PPC_MSI_BITMAP)   += msi_bitmap.o
 
 obj-$(CONFIG_PPC_MPC106)       += grackle.o
 obj-$(CONFIG_PPC_DCR_NATIVE)   += dcr-low.o
@@ -15,6 +16,7 @@ obj-$(CONFIG_FSL_SOC)         += fsl_soc.o
 obj-$(CONFIG_FSL_PCI)          += fsl_pci.o $(fsl-msi-obj-y)
 obj-$(CONFIG_FSL_LBC)          += fsl_lbc.o
 obj-$(CONFIG_FSL_GTM)          += fsl_gtm.o
+obj-$(CONFIG_MPC8xxx_GPIO)     += mpc8xxx_gpio.o
 obj-$(CONFIG_RAPIDIO)          += fsl_rio.o
 obj-$(CONFIG_TSI108_BRIDGE)    += tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE)     += qe_lib/
@@ -36,15 +38,12 @@ ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_4xx)              += ppc4xx_pci.o
 endif
 
-# Temporary hack until we have migrated to asm-powerpc
-ifeq ($(ARCH),powerpc)
 obj-$(CONFIG_CPM)              += cpm_common.o
 obj-$(CONFIG_CPM2)             += cpm2.o cpm2_pic.o
 obj-$(CONFIG_QUICC_ENGINE)     += cpm_common.o
 obj-$(CONFIG_PPC_DCR)          += dcr.o
 obj-$(CONFIG_8xx)              += mpc8xx_pic.o cpm1.o
 obj-$(CONFIG_UCODE_PATCH)      += micropatch.o
-endif
 
 ifeq ($(CONFIG_SUSPEND),y)
 obj-$(CONFIG_6xx)              += 6xx-suspend.o
index 4a04823e8423b9f8a24098a2fec81acf917598a9..490473ce81030475fbfa6075a2c76612dcd48b0e 100644 (file)
@@ -546,15 +546,11 @@ static int cpm1_gpio16_get(struct gpio_chip *gc, unsigned int gpio)
        return !!(in_be16(&iop->dat) & pin_mask);
 }
 
-static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
+static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask,
+       int value)
 {
-       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
        struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
        struct cpm_ioport16 __iomem *iop = mm_gc->regs;
-       unsigned long flags;
-       u16 pin_mask = 1 << (15 - gpio);
-
-       spin_lock_irqsave(&cpm1_gc->lock, flags);
 
        if (value)
                cpm1_gc->cpdata |= pin_mask;
@@ -562,6 +558,18 @@ static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
                cpm1_gc->cpdata &= ~pin_mask;
 
        out_be16(&iop->dat, cpm1_gc->cpdata);
+}
+
+static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+       unsigned long flags;
+       u16 pin_mask = 1 << (15 - gpio);
+
+       spin_lock_irqsave(&cpm1_gc->lock, flags);
+
+       __cpm1_gpio16_set(mm_gc, pin_mask, value);
 
        spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 }
@@ -569,14 +577,17 @@ static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
 static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
        struct cpm_ioport16 __iomem *iop = mm_gc->regs;
-       u16 pin_mask;
+       unsigned long flags;
+       u16 pin_mask = 1 << (15 - gpio);
 
-       pin_mask = 1 << (15 - gpio);
+       spin_lock_irqsave(&cpm1_gc->lock, flags);
 
        setbits16(&iop->dir, pin_mask);
+       __cpm1_gpio16_set(mm_gc, pin_mask, val);
 
-       cpm1_gpio16_set(gc, gpio, val);
+       spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 
        return 0;
 }
@@ -584,13 +595,17 @@ static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 static int cpm1_gpio16_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
        struct cpm_ioport16 __iomem *iop = mm_gc->regs;
-       u16 pin_mask;
+       unsigned long flags;
+       u16 pin_mask = 1 << (15 - gpio);
 
-       pin_mask = 1 << (15 - gpio);
+       spin_lock_irqsave(&cpm1_gc->lock, flags);
 
        clrbits16(&iop->dir, pin_mask);
 
+       spin_unlock_irqrestore(&cpm1_gc->lock, flags);
+
        return 0;
 }
 
@@ -655,15 +670,11 @@ static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
        return !!(in_be32(&iop->dat) & pin_mask);
 }
 
-static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
+static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask,
+       int value)
 {
-       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
        struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
        struct cpm_ioport32b __iomem *iop = mm_gc->regs;
-       unsigned long flags;
-       u32 pin_mask = 1 << (31 - gpio);
-
-       spin_lock_irqsave(&cpm1_gc->lock, flags);
 
        if (value)
                cpm1_gc->cpdata |= pin_mask;
@@ -671,6 +682,18 @@ static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
                cpm1_gc->cpdata &= ~pin_mask;
 
        out_be32(&iop->dat, cpm1_gc->cpdata);
+}
+
+static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
+       unsigned long flags;
+       u32 pin_mask = 1 << (31 - gpio);
+
+       spin_lock_irqsave(&cpm1_gc->lock, flags);
+
+       __cpm1_gpio32_set(mm_gc, pin_mask, value);
 
        spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 }
@@ -678,14 +701,17 @@ static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
 static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
        struct cpm_ioport32b __iomem *iop = mm_gc->regs;
-       u32 pin_mask;
+       unsigned long flags;
+       u32 pin_mask = 1 << (31 - gpio);
 
-       pin_mask = 1 << (31 - gpio);
+       spin_lock_irqsave(&cpm1_gc->lock, flags);
 
        setbits32(&iop->dir, pin_mask);
+       __cpm1_gpio32_set(mm_gc, pin_mask, val);
 
-       cpm1_gpio32_set(gc, gpio, val);
+       spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 
        return 0;
 }
@@ -693,13 +719,17 @@ static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
        struct cpm_ioport32b __iomem *iop = mm_gc->regs;
-       u32 pin_mask;
+       unsigned long flags;
+       u32 pin_mask = 1 << (31 - gpio);
 
-       pin_mask = 1 << (31 - gpio);
+       spin_lock_irqsave(&cpm1_gc->lock, flags);
 
        clrbits32(&iop->dir, pin_mask);
 
+       spin_unlock_irqrestore(&cpm1_gc->lock, flags);
+
        return 0;
 }
 
index 422c8faef5938d38f0f57da4e8018bf11e3b975b..0494ee55920f7c55f6aac6c2447a0cd7c2ad76c0 100644 (file)
  * (at your option) any later version.
  */
 
+#include <linux/init.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/io.h>
 #include <linux/of.h>
+#include <asm/prom.h>
 #include <asm/fsl_lbc.h>
 
-spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
-
-struct fsl_lbc_regs __iomem *fsl_lbc_regs;
-EXPORT_SYMBOL(fsl_lbc_regs);
+static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
+static struct fsl_lbc_regs __iomem *fsl_lbc_regs;
 
 static char __initdata *compat_lbc[] = {
        "fsl,pq2-localbus",
@@ -127,3 +132,43 @@ int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm)
        return 0;
 }
 EXPORT_SYMBOL(fsl_upm_find);
+
+/**
+ * fsl_upm_run_pattern - actually run an UPM pattern
+ * @upm:       pointer to the fsl_upm structure obtained via fsl_upm_find
+ * @io_base:   remapped pointer to where memory access should happen
+ * @mar:       MAR register content during pattern execution
+ *
+ * This function triggers dummy write to the memory specified by the io_base,
+ * thus UPM pattern actually executed. Note that mar usage depends on the
+ * pre-programmed AMX bits in the UPM RAM.
+ */
+int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
+{
+       int ret = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&fsl_lbc_lock, flags);
+
+       out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
+
+       switch (upm->width) {
+       case 8:
+               out_8(io_base, 0x0);
+               break;
+       case 16:
+               out_be16(io_base, 0x0);
+               break;
+       case 32:
+               out_be32(io_base, 0x0);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       spin_unlock_irqrestore(&fsl_lbc_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(fsl_upm_run_pattern);
index 2c5187cc8a24e31e45aaf2a107677fbd9ce81d3f..f25ce818d40a16061e40209309c78c6fce4ad9c0 100644 (file)
@@ -14,7 +14,6 @@
  */
 #include <linux/irq.h>
 #include <linux/bootmem.h>
-#include <linux/bitmap.h>
 #include <linux/msi.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
@@ -67,95 +66,22 @@ static struct irq_host_ops fsl_msi_host_ops = {
        .map = fsl_msi_host_map,
 };
 
-static irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num)
-{
-       unsigned long flags;
-       int order = get_count_order(num);
-       int offset;
-
-       spin_lock_irqsave(&msi->bitmap_lock, flags);
-
-       offset = bitmap_find_free_region(msi->fsl_msi_bitmap,
-                                       NR_MSI_IRQS, order);
-
-       spin_unlock_irqrestore(&msi->bitmap_lock, flags);
-
-       pr_debug("%s: allocated 0x%x (2^%d) at offset 0x%x\n",
-               __func__, num, order, offset);
-
-       return offset;
-}
-
-static void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num)
-{
-       unsigned long flags;
-       int order = get_count_order(num);
-
-       pr_debug("%s: freeing 0x%x (2^%d) at offset 0x%x\n",
-               __func__, num, order, offset);
-
-       spin_lock_irqsave(&msi->bitmap_lock, flags);
-       bitmap_release_region(msi->fsl_msi_bitmap, offset, order);
-       spin_unlock_irqrestore(&msi->bitmap_lock, flags);
-}
-
-static int fsl_msi_free_dt_hwirqs(struct fsl_msi *msi)
-{
-       int i;
-       int len;
-       const u32 *p;
-
-       bitmap_allocate_region(msi->fsl_msi_bitmap, 0,
-                      get_count_order(NR_MSI_IRQS));
-
-       p = of_get_property(msi->of_node, "msi-available-ranges", &len);
-
-       if (!p) {
-               /* No msi-available-ranges property,
-                * All the 256 MSI interrupts can be used
-                */
-               fsl_msi_free_hwirqs(msi, 0, 0x100);
-               return 0;
-       }
-
-       if ((len % (2 * sizeof(u32))) != 0) {
-               printk(KERN_WARNING "fsl_msi: Malformed msi-available-ranges "
-                      "property on %s\n", msi->of_node->full_name);
-               return -EINVAL;
-       }
-
-       /* Format is: (<u32 start> <u32 count>)+ */
-       len /= 2 * sizeof(u32);
-       for (i = 0; i < len; i++, p += 2)
-               fsl_msi_free_hwirqs(msi, *p, *(p + 1));
-
-       return 0;
-}
-
 static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
 {
        int rc;
-       int size = BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(u32);
 
-       msi_data->fsl_msi_bitmap = kzalloc(size, GFP_KERNEL);
+       rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS,
+                             msi_data->irqhost->of_node);
+       if (rc)
+               return rc;
 
-       if (msi_data->fsl_msi_bitmap == NULL) {
-               pr_debug("%s: ENOMEM allocating allocator bitmap!\n",
-                               __func__);
-               return -ENOMEM;
+       rc = msi_bitmap_reserve_dt_hwirqs(&msi_data->bitmap);
+       if (rc < 0) {
+               msi_bitmap_free(&msi_data->bitmap);
+               return rc;
        }
 
-       rc = fsl_msi_free_dt_hwirqs(msi_data);
-       if (rc)
-               goto out_free;
-
        return 0;
-out_free:
-       kfree(msi_data->fsl_msi_bitmap);
-
-       msi_data->fsl_msi_bitmap = NULL;
-       return rc;
-
 }
 
 static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
@@ -175,7 +101,8 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
                if (entry->irq == NO_IRQ)
                        continue;
                set_irq_msi(entry->irq, NULL);
-               fsl_msi_free_hwirqs(msi_data, virq_to_hw(entry->irq), 1);
+               msi_bitmap_free_hwirqs(&msi_data->bitmap,
+                                      virq_to_hw(entry->irq), 1);
                irq_dispose_mapping(entry->irq);
        }
 
@@ -197,15 +124,14 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
 
 static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
-       irq_hw_number_t hwirq;
-       int rc;
+       int rc, hwirq;
        unsigned int virq;
        struct msi_desc *entry;
        struct msi_msg msg;
        struct fsl_msi *msi_data = fsl_msi;
 
        list_for_each_entry(entry, &pdev->msi_list, list) {
-               hwirq = fsl_msi_alloc_hwirqs(msi_data, 1);
+               hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
                if (hwirq < 0) {
                        rc = hwirq;
                        pr_debug("%s: fail allocating msi interrupt\n",
@@ -216,9 +142,9 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                virq = irq_create_mapping(msi_data->irqhost, hwirq);
 
                if (virq == NO_IRQ) {
-                       pr_debug("%s: fail mapping hwirq 0x%lx\n",
+                       pr_debug("%s: fail mapping hwirq 0x%x\n",
                                        __func__, hwirq);
-                       fsl_msi_free_hwirqs(msi_data, hwirq, 1);
+                       msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
                        rc = -ENOSPC;
                        goto out_free;
                }
@@ -317,14 +243,11 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
                goto error_out;
        }
 
-       msi->of_node = of_node_get(dev->node);
+       msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR,
+                                     NR_MSI_IRQS, &fsl_msi_host_ops, 0);
 
-       msi->irqhost = irq_alloc_host(of_node_get(dev->node),
-                               IRQ_HOST_MAP_LINEAR,
-                               NR_MSI_IRQS, &fsl_msi_host_ops, 0);
        if (msi->irqhost == NULL) {
                dev_err(&dev->dev, "No memory for MSI irqhost\n");
-               of_node_put(dev->node);
                err = -ENOMEM;
                goto error_out;
        }
index a653468521fa36b1050e32ba5032b4ed686fee6f..331c7e7025b786bf7d3ed071038ceb6330f971fc 100644 (file)
@@ -13,6 +13,8 @@
 #ifndef _POWERPC_SYSDEV_FSL_MSI_H
 #define _POWERPC_SYSDEV_FSL_MSI_H
 
+#include <asm/msi_bitmap.h>
+
 #define NR_MSI_REG             8
 #define IRQS_PER_MSI_REG       32
 #define NR_MSI_IRQS    (NR_MSI_REG * IRQS_PER_MSI_REG)
@@ -22,9 +24,6 @@
 #define FSL_PIC_IP_IPIC        0x00000002
 
 struct fsl_msi {
-       /* Device node of the MSI interrupt*/
-       struct device_node *of_node;
-
        struct irq_host *irqhost;
 
        unsigned long cascade_irq;
@@ -34,8 +33,7 @@ struct fsl_msi {
        void __iomem *msi_regs;
        u32 feature;
 
-       unsigned long *fsl_msi_bitmap;
-       spinlock_t bitmap_lock;
+       struct msi_bitmap bitmap;
 };
 
 #endif /* _POWERPC_SYSDEV_FSL_MSI_H */
index 61e6d77efa4fcec7d17fe31d6b5763786ba58319..5b264eb4b1f7f6af12115640ed8c17d139cb9e3b 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * MPC85xx/86xx PCI/PCIE support routing.
+ * MPC83xx/85xx/86xx PCI/PCIE support routing.
  *
- * Copyright 2007 Freescale Semiconductor, Inc
+ * Copyright 2007,2008 Freescale Semiconductor, Inc
  *
  * Initial author: Xianghua Xiao <x.xiao@freescale.com>
  * Recode: ZHANG WEI <wei.zhang@freescale.com>
@@ -251,20 +251,47 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
 #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
 
-#if defined(CONFIG_PPC_83xx)
+#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
 int __init mpc83xx_add_bridge(struct device_node *dev)
 {
        int len;
        struct pci_controller *hose;
-       struct resource rsrc;
+       struct resource rsrc_reg;
+       struct resource rsrc_cfg;
        const int *bus_range;
-       int primary = 1, has_address = 0;
-       phys_addr_t immr = get_immrbase();
+       int primary;
 
        pr_debug("Adding PCI host bridge %s\n", dev->full_name);
 
        /* Fetch host bridge registers address */
-       has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+       if (of_address_to_resource(dev, 0, &rsrc_reg)) {
+               printk(KERN_WARNING "Can't get pci register base!\n");
+               return -ENOMEM;
+       }
+
+       memset(&rsrc_cfg, 0, sizeof(rsrc_cfg));
+
+       if (of_address_to_resource(dev, 1, &rsrc_cfg)) {
+               printk(KERN_WARNING
+                       "No pci config register base in dev tree, "
+                       "using default\n");
+               /*
+                * MPC83xx supports up to two host controllers
+                *      one at 0x8500 has config space registers at 0x8300
+                *      one at 0x8600 has config space registers at 0x8380
+                */
+               if ((rsrc_reg.start & 0xfffff) == 0x8500)
+                       rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300;
+               else if ((rsrc_reg.start & 0xfffff) == 0x8600)
+                       rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380;
+       }
+       /*
+        * Controller at offset 0x8500 is primary
+        */
+       if ((rsrc_reg.start & 0xfffff) == 0x8500)
+               primary = 1;
+       else
+               primary = 0;
 
        /* Get bus range if any */
        bus_range = of_get_property(dev, "bus-range", &len);
@@ -281,22 +308,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
        hose->first_busno = bus_range ? bus_range[0] : 0;
        hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
-       /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar
-        * the other at 0x8600, we consider the 0x8500 the primary controller
-        */
-       /* PCI 1 */
-       if ((rsrc.start & 0xfffff) == 0x8500) {
-               setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0);
-       }
-       /* PCI 2 */
-       if ((rsrc.start & 0xfffff) == 0x8600) {
-               setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0);
-               primary = 0;
-       }
+       setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0);
 
-       printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
+       printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
               "Firmware bus number: %d->%d\n",
-              (unsigned long long)rsrc.start, hose->first_busno,
+              (unsigned long long)rsrc_reg.start, hose->first_busno,
               hose->last_busno);
 
        pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
index 214388e11807a039d05a9d6baf4fcf1a25b2f18a..01b884b25696847d6c58817169156c49e49c11e0 100644 (file)
@@ -412,53 +412,6 @@ err:
 
 arch_initcall(gfar_of_init);
 
-
-#ifdef CONFIG_PPC_83xx
-static int __init mpc83xx_wdt_init(void)
-{
-       struct resource r;
-       struct device_node *np;
-       struct platform_device *dev;
-       u32 freq = fsl_get_sys_freq();
-       int ret;
-
-       np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
-
-       if (!np) {
-               ret = -ENODEV;
-               goto nodev;
-       }
-
-       memset(&r, 0, sizeof(r));
-
-       ret = of_address_to_resource(np, 0, &r);
-       if (ret)
-               goto err;
-
-       dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
-       if (IS_ERR(dev)) {
-               ret = PTR_ERR(dev);
-               goto err;
-       }
-
-       ret = platform_device_add_data(dev, &freq, sizeof(freq));
-       if (ret)
-               goto unreg;
-
-       of_node_put(np);
-       return 0;
-
-unreg:
-       platform_device_unregister(dev);
-err:
-       of_node_put(np);
-nodev:
-       return ret;
-}
-
-arch_initcall(mpc83xx_wdt_init);
-#endif
-
 static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
 {
        if (!phy_type)
@@ -767,42 +720,6 @@ void fsl_rstcr_restart(char *cmd)
 #endif
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-struct platform_diu_data_ops diu_ops = {
-       .diu_size = 1280 * 1024 * 4,    /* default one 1280x1024 buffer */
-};
+struct platform_diu_data_ops diu_ops;
 EXPORT_SYMBOL(diu_ops);
-
-int __init preallocate_diu_videomemory(void)
-{
-       pr_debug("diu_size=%lu\n", diu_ops.diu_size);
-
-       diu_ops.diu_mem = __alloc_bootmem(diu_ops.diu_size, 8, 0);
-       if (!diu_ops.diu_mem) {
-               printk(KERN_ERR "fsl-diu: cannot allocate %lu bytes\n",
-                       diu_ops.diu_size);
-               return -ENOMEM;
-       }
-
-       pr_debug("diu_mem=%p\n", diu_ops.diu_mem);
-
-       rh_init(&diu_ops.diu_rh_info, 4096, ARRAY_SIZE(diu_ops.diu_rh_block),
-               diu_ops.diu_rh_block);
-       return rh_attach_region(&diu_ops.diu_rh_info,
-                               (unsigned long) diu_ops.diu_mem,
-                               diu_ops.diu_size);
-}
-
-static int __init early_parse_diufb(char *p)
-{
-       if (!p)
-               return 1;
-
-       diu_ops.diu_size = _ALIGN_UP(memparse(p, &p), 8);
-
-       pr_debug("diu_size=%lu\n", diu_ops.diu_size);
-
-       return 0;
-}
-early_param("diufb", early_parse_diufb);
-
 #endif
index 0242998873526c32ada0e52e3b3f45283f407395..60f7f227327ce04dbb0fc81c82e424bfbfcdb2a8 100644 (file)
@@ -20,14 +20,7 @@ extern int fsl_spi_init(struct spi_board_info *board_infos,
 extern void fsl_rstcr_restart(char *cmd);
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-#include <linux/bootmem.h>
-#include <asm/rheap.h>
 struct platform_diu_data_ops {
-       rh_block_t diu_rh_block[16];
-       rh_info_t diu_rh_info;
-       unsigned long diu_size;
-       void *diu_mem;
-
        unsigned int (*get_pixel_format) (unsigned int bits_per_pixel,
                int monitor_port);
        void (*set_gamma_table) (int monitor_port, char *gamma_table_base);
@@ -38,7 +31,6 @@ struct platform_diu_data_ops {
 };
 
 extern struct platform_diu_data_ops diu_ops;
-int __init preallocate_diu_videomemory(void);
 #endif
 
 #endif
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
new file mode 100644 (file)
index 0000000..103eace
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * GPIOs on MPC8349/8572/8610 and compatible
+ *
+ * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+
+#define MPC8XXX_GPIO_PINS      32
+
+#define GPIO_DIR               0x00
+#define GPIO_ODR               0x04
+#define GPIO_DAT               0x08
+#define GPIO_IER               0x0c
+#define GPIO_IMR               0x10
+#define GPIO_ICR               0x14
+
+struct mpc8xxx_gpio_chip {
+       struct of_mm_gpio_chip mm_gc;
+       spinlock_t lock;
+
+       /*
+        * shadowed data register to be able to clear/set output pins in
+        * open drain mode safely
+        */
+       u32 data;
+};
+
+static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
+{
+       return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
+}
+
+static inline struct mpc8xxx_gpio_chip *
+to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
+{
+       return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
+}
+
+static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+       mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
+}
+
+static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+
+       return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
+}
+
+static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       if (val)
+               mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
+       else
+               mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
+
+       out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+
+       return 0;
+}
+
+static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+
+       mpc8xxx_gpio_set(gc, gpio, val);
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+
+       return 0;
+}
+
+static void __init mpc8xxx_add_controller(struct device_node *np)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc;
+       struct of_mm_gpio_chip *mm_gc;
+       struct of_gpio_chip *of_gc;
+       struct gpio_chip *gc;
+       int ret;
+
+       mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
+       if (!mpc8xxx_gc) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       spin_lock_init(&mpc8xxx_gc->lock);
+
+       mm_gc = &mpc8xxx_gc->mm_gc;
+       of_gc = &mm_gc->of_gc;
+       gc = &of_gc->gc;
+
+       mm_gc->save_regs = mpc8xxx_gpio_save_regs;
+       of_gc->gpio_cells = 2;
+       gc->ngpio = MPC8XXX_GPIO_PINS;
+       gc->direction_input = mpc8xxx_gpio_dir_in;
+       gc->direction_output = mpc8xxx_gpio_dir_out;
+       gc->get = mpc8xxx_gpio_get;
+       gc->set = mpc8xxx_gpio_set;
+
+       ret = of_mm_gpiochip_add(np, mm_gc);
+       if (ret)
+               goto err;
+
+       return;
+
+err:
+       pr_err("%s: registration failed with status %d\n",
+              np->full_name, ret);
+       kfree(mpc8xxx_gc);
+
+       return;
+}
+
+static int __init mpc8xxx_add_gpiochips(void)
+{
+       struct device_node *np;
+
+       for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio")
+               mpc8xxx_add_controller(np);
+
+       for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio")
+               mpc8xxx_add_controller(np);
+
+       for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio")
+               mpc8xxx_add_controller(np);
+
+       return 0;
+}
+arch_initcall(mpc8xxx_add_gpiochips);
index fbf8a266941c27ba6ff54867c8c2fab3a56d5690..6209c62a426d1177cb574a1bf92f0dc6f7ed7b43 100644 (file)
@@ -14,8 +14,6 @@
 #ifdef CONFIG_PCI_MSI
 extern void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq);
 extern int mpic_msi_init_allocator(struct mpic *mpic);
-extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num);
-extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num);
 extern int mpic_u3msi_init(struct mpic *mpic);
 extern int mpic_pasemi_msi_init(struct mpic *mpic);
 #else
index de3e5e8bc3241e297ed321b240fb95edaa4350e2..1d44eee80fa1275c5527967a4edf3a57f5f53f7f 100644 (file)
 #include <asm/prom.h>
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
+#include <asm/msi_bitmap.h>
 
 #include <sysdev/mpic.h>
 
-static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
-{
-       pr_debug("mpic: reserving hwirq 0x%lx\n", hwirq);
-       bitmap_allocate_region(mpic->hwirq_bitmap, hwirq, 0);
-}
-
 void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
 {
-       unsigned long flags;
-
        /* The mpic calls this even when there is no allocator setup */
-       if (!mpic->hwirq_bitmap)
+       if (!mpic->msi_bitmap.bitmap)
                return;
 
-       spin_lock_irqsave(&mpic->bitmap_lock, flags);
-       __mpic_msi_reserve_hwirq(mpic, hwirq);
-       spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
-}
-
-irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num)
-{
-       unsigned long flags;
-       int offset, order = get_count_order(num);
-
-       spin_lock_irqsave(&mpic->bitmap_lock, flags);
-       /*
-        * This is fast, but stricter than we need. We might want to add
-        * a fallback routine which does a linear search with no alignment.
-        */
-       offset = bitmap_find_free_region(mpic->hwirq_bitmap, mpic->irq_count,
-                                        order);
-       spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
-
-       pr_debug("mpic: allocated 0x%x (2^%d) at offset 0x%x\n",
-                num, order, offset);
-
-       return offset;
-}
-
-void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num)
-{
-       unsigned long flags;
-       int order = get_count_order(num);
-
-       pr_debug("mpic: freeing 0x%x (2^%d) at offset 0x%x\n",
-                num, order, offset);
-
-       spin_lock_irqsave(&mpic->bitmap_lock, flags);
-       bitmap_release_region(mpic->hwirq_bitmap, offset, order);
-       spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+       msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
 }
 
 #ifdef CONFIG_MPIC_U3_HT_IRQS
@@ -83,13 +41,13 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
 
        /* Reserve source numbers we know are reserved in the HW */
        for (i = 0;   i < 8;   i++)
-               __mpic_msi_reserve_hwirq(mpic, i);
+               msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
        for (i = 42;  i < 46;  i++)
-               __mpic_msi_reserve_hwirq(mpic, i);
+               msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
        for (i = 100; i < 105; i++)
-               __mpic_msi_reserve_hwirq(mpic, i);
+               msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
        np = NULL;
        while ((np = of_find_all_nodes(np))) {
@@ -99,7 +57,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
                while (of_irq_map_one(np, index++, &oirq) == 0) {
                        ops->xlate(mpic->irqhost, NULL, oirq.specifier,
                                                oirq.size, &hwirq, &flags);
-                       __mpic_msi_reserve_hwirq(mpic, hwirq);
+                       msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
                }
        }
 
@@ -112,70 +70,25 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
 }
 #endif
 
-static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic)
-{
-       int i, len;
-       const u32 *p;
-
-       p = of_get_property(mpic->irqhost->of_node,
-                           "msi-available-ranges", &len);
-       if (!p) {
-               pr_debug("mpic: no msi-available-ranges property found on %s\n",
-                         mpic->irqhost->of_node->full_name);
-               return -ENODEV;
-       }
-
-       if (len % 8 != 0) {
-               printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
-                      "property on %s\n", mpic->irqhost->of_node->full_name);
-               return -EINVAL;
-       }
-
-       bitmap_allocate_region(mpic->hwirq_bitmap, 0,
-                              get_count_order(mpic->irq_count));
-
-       /* Format is: (<u32 start> <u32 count>)+ */
-       len /= sizeof(u32);
-       for (i = 0; i < len / 2; i++, p += 2)
-               mpic_msi_free_hwirqs(mpic, *p, *(p + 1));
-
-       return 0;
-}
-
 int mpic_msi_init_allocator(struct mpic *mpic)
 {
-       int rc, size;
-
-       BUG_ON(mpic->hwirq_bitmap);
-       spin_lock_init(&mpic->bitmap_lock);
+       int rc;
 
-       size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long);
-       pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size);
+       rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->irq_count,
+                             mpic->irqhost->of_node);
+       if (rc)
+               return rc;
 
-       mpic->hwirq_bitmap = alloc_maybe_bootmem(size, GFP_KERNEL);
-
-       if (!mpic->hwirq_bitmap) {
-               pr_debug("mpic: ENOMEM allocating allocator bitmap!\n");
-               return -ENOMEM;
-       }
-
-       memset(mpic->hwirq_bitmap, 0, size);
-
-       rc = mpic_msi_reserve_dt_hwirqs(mpic);
-       if (rc) {
+       rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap);
+       if (rc > 0) {
                if (mpic->flags & MPIC_U3_HT_IRQS)
                        rc = mpic_msi_reserve_u3_hwirqs(mpic);
 
-               if (rc)
-                       goto out_free;
+               if (rc) {
+                       msi_bitmap_free(&mpic->msi_bitmap);
+                       return rc;
+               }
        }
 
        return 0;
-
- out_free:
-       if (mem_init_done)
-               kfree(mpic->hwirq_bitmap);
-
-       mpic->hwirq_bitmap = NULL;
-       return rc;
 }
index 68aff6076675a433fe1144c20eff86e85e4c37c1..656cb772b6910458392cc2cc0c5001fced632189 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/prom.h>
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
+#include <asm/msi_bitmap.h>
 
 #include "mpic.h"
 
@@ -81,8 +82,8 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
                        continue;
 
                set_irq_msi(entry->irq, NULL);
-               mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq),
-                                    ALLOC_CHUNK);
+               msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
+                                      virq_to_hw(entry->irq), ALLOC_CHUNK);
                irq_dispose_mapping(entry->irq);
        }
 
@@ -91,11 +92,10 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
 
 static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
-       irq_hw_number_t hwirq;
        unsigned int virq;
        struct msi_desc *entry;
        struct msi_msg msg;
-       int ret;
+       int hwirq;
 
        pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
                 pdev, nvec, type);
@@ -109,17 +109,19 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                 * few MSIs for someone, but restrictions will apply to how the
                 * sources can be changed independently.
                 */
-               ret = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK);
-               hwirq = ret;
-               if (ret < 0) {
+               hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap,
+                                               ALLOC_CHUNK);
+               if (hwirq < 0) {
                        pr_debug("pasemi_msi: failed allocating hwirq\n");
                        return hwirq;
                }
 
                virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
                if (virq == NO_IRQ) {
-                       pr_debug("pasemi_msi: failed mapping hwirq 0x%lx\n", hwirq);
-                       mpic_msi_free_hwirqs(msi_mpic, hwirq, ALLOC_CHUNK);
+                       pr_debug("pasemi_msi: failed mapping hwirq 0x%x\n",
+                                 hwirq);
+                       msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq,
+                                              ALLOC_CHUNK);
                        return -ENOSPC;
                }
 
@@ -133,8 +135,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                set_irq_chip(virq, &mpic_pasemi_msi_chip);
                set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
 
-               pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%x\n",
-                         virq, hwirq, msg.address_lo);
+               pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%x) " \
+                        "addr 0x%x\n", virq, hwirq, msg.address_lo);
 
                /* Likewise, the device writes [0...511] into the target
                 * register to generate MSI [512...1023]
index 6e2f8686fdfc0471946b8344f75ed70c042150e3..0a8f5a9e87c94d48b040735d156d1e6ff298ee62 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/prom.h>
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
+#include <asm/msi_bitmap.h>
 
 #include "mpic.h"
 
@@ -101,7 +102,8 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
                        continue;
 
                set_irq_msi(entry->irq, NULL);
-               mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), 1);
+               msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
+                                      virq_to_hw(entry->irq), 1);
                irq_dispose_mapping(entry->irq);
        }
 
@@ -110,29 +112,27 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
 
 static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
-       irq_hw_number_t hwirq;
        unsigned int virq;
        struct msi_desc *entry;
        struct msi_msg msg;
        u64 addr;
-       int ret;
+       int hwirq;
 
        addr = find_ht_magic_addr(pdev);
        msg.address_lo = addr & 0xFFFFFFFF;
        msg.address_hi = addr >> 32;
 
        list_for_each_entry(entry, &pdev->msi_list, list) {
-               ret = mpic_msi_alloc_hwirqs(msi_mpic, 1);
-               if (ret < 0) {
+               hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
+               if (hwirq < 0) {
                        pr_debug("u3msi: failed allocating hwirq\n");
-                       return ret;
+                       return hwirq;
                }
-               hwirq = ret;
 
                virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
                if (virq == NO_IRQ) {
-                       pr_debug("u3msi: failed mapping hwirq 0x%lx\n", hwirq);
-                       mpic_msi_free_hwirqs(msi_mpic, hwirq, 1);
+                       pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq);
+                       msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
                        return -ENOSPC;
                }
 
@@ -140,8 +140,8 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                set_irq_chip(virq, &mpic_u3msi_chip);
                set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
 
-               pr_debug("u3msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n",
-                         virq, hwirq, addr);
+               pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
+                         virq, hwirq, (unsigned long)addr);
 
                msg.data = hwirq;
                write_msi_msg(virq, &msg);
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c
new file mode 100644 (file)
index 0000000..f84217b
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2006-2008, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <asm/msi_bitmap.h>
+
+int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num)
+{
+       unsigned long flags;
+       int offset, order = get_count_order(num);
+
+       spin_lock_irqsave(&bmp->lock, flags);
+       /*
+        * This is fast, but stricter than we need. We might want to add
+        * a fallback routine which does a linear search with no alignment.
+        */
+       offset = bitmap_find_free_region(bmp->bitmap, bmp->irq_count, order);
+       spin_unlock_irqrestore(&bmp->lock, flags);
+
+       pr_debug("msi_bitmap: allocated 0x%x (2^%d) at offset 0x%x\n",
+                num, order, offset);
+
+       return offset;
+}
+
+void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset,
+                           unsigned int num)
+{
+       unsigned long flags;
+       int order = get_count_order(num);
+
+       pr_debug("msi_bitmap: freeing 0x%x (2^%d) at offset 0x%x\n",
+                num, order, offset);
+
+       spin_lock_irqsave(&bmp->lock, flags);
+       bitmap_release_region(bmp->bitmap, offset, order);
+       spin_unlock_irqrestore(&bmp->lock, flags);
+}
+
+void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq)
+{
+       unsigned long flags;
+
+       pr_debug("msi_bitmap: reserving hwirq 0x%x\n", hwirq);
+
+       spin_lock_irqsave(&bmp->lock, flags);
+       bitmap_allocate_region(bmp->bitmap, hwirq, 0);
+       spin_unlock_irqrestore(&bmp->lock, flags);
+}
+
+/**
+ * msi_bitmap_reserve_dt_hwirqs - Reserve irqs specified in the device tree.
+ * @bmp: pointer to the MSI bitmap.
+ *
+ * Looks in the device tree to see if there is a property specifying which
+ * irqs can be used for MSI. If found those irqs reserved in the device tree
+ * are reserved in the bitmap.
+ *
+ * Returns 0 for success, < 0 if there was an error, and > 0 if no property
+ * was found in the device tree.
+ **/
+int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp)
+{
+       int i, j, len;
+       const u32 *p;
+
+       if (!bmp->of_node)
+               return 1;
+
+       p = of_get_property(bmp->of_node, "msi-available-ranges", &len);
+       if (!p) {
+               pr_debug("msi_bitmap: no msi-available-ranges property " \
+                        "found on %s\n", bmp->of_node->full_name);
+               return 1;
+       }
+
+       if (len % (2 * sizeof(u32)) != 0) {
+               printk(KERN_WARNING "msi_bitmap: Malformed msi-available-ranges"
+                      " property on %s\n", bmp->of_node->full_name);
+               return -EINVAL;
+       }
+
+       bitmap_allocate_region(bmp->bitmap, 0, get_count_order(bmp->irq_count));
+
+       spin_lock(&bmp->lock);
+
+       /* Format is: (<u32 start> <u32 count>)+ */
+       len /= 2 * sizeof(u32);
+       for (i = 0; i < len; i++, p += 2) {
+               for (j = 0; j < *(p + 1); j++)
+                       bitmap_release_region(bmp->bitmap, *p + j, 0);
+       }
+
+       spin_unlock(&bmp->lock);
+
+       return 0;
+}
+
+int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
+                    struct device_node *of_node)
+{
+       int size;
+
+       if (!irq_count)
+               return -EINVAL;
+
+       size = BITS_TO_LONGS(irq_count) * sizeof(long);
+       pr_debug("msi_bitmap: allocator bitmap size is 0x%x bytes\n", size);
+
+       bmp->bitmap = zalloc_maybe_bootmem(size, GFP_KERNEL);
+       if (!bmp->bitmap) {
+               pr_debug("msi_bitmap: ENOMEM allocating allocator bitmap!\n");
+               return -ENOMEM;
+       }
+
+       /* We zalloc'ed the bitmap, so all irqs are free by default */
+       spin_lock_init(&bmp->lock);
+       bmp->of_node = of_node_get(of_node);
+       bmp->irq_count = irq_count;
+
+       return 0;
+}
+
+void msi_bitmap_free(struct msi_bitmap *bmp)
+{
+       /* we can't free the bitmap we don't know if it's bootmem etc. */
+       of_node_put(bmp->of_node);
+       bmp->bitmap = NULL;
+}
+
+#ifdef CONFIG_MSI_BITMAP_SELFTEST
+
+#define check(x)       \
+       if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__);
+
+void test_basics(void)
+{
+       struct msi_bitmap bmp;
+       int i, size = 512;
+
+       /* Can't allocate a bitmap of 0 irqs */
+       check(msi_bitmap_alloc(&bmp, 0, NULL) != 0);
+
+       /* of_node may be NULL */
+       check(0 == msi_bitmap_alloc(&bmp, size, NULL));
+
+       /* Should all be free by default */
+       check(0 == bitmap_find_free_region(bmp.bitmap, size,
+                                          get_count_order(size)));
+       bitmap_release_region(bmp.bitmap, 0, get_count_order(size));
+
+       /* With no node, there's no msi-available-ranges, so expect > 0 */
+       check(msi_bitmap_reserve_dt_hwirqs(&bmp) > 0);
+
+       /* Should all still be free */
+       check(0 == bitmap_find_free_region(bmp.bitmap, size,
+                                          get_count_order(size)));
+       bitmap_release_region(bmp.bitmap, 0, get_count_order(size));
+
+       /* Check we can fill it up and then no more */
+       for (i = 0; i < size; i++)
+               check(msi_bitmap_alloc_hwirqs(&bmp, 1) >= 0);
+
+       check(msi_bitmap_alloc_hwirqs(&bmp, 1) < 0);
+
+       /* Should all be allocated */
+       check(bitmap_find_free_region(bmp.bitmap, size, 0) < 0);
+
+       /* And if we free one we can then allocate another */
+       msi_bitmap_free_hwirqs(&bmp, size / 2, 1);
+       check(msi_bitmap_alloc_hwirqs(&bmp, 1) == size / 2);
+
+       msi_bitmap_free(&bmp);
+
+       /* Clients may check bitmap == NULL for "not-allocated" */
+       check(bmp.bitmap == NULL);
+
+       kfree(bmp.bitmap);
+}
+
+void test_of_node(void)
+{
+       u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 };
+       const char *expected_str = "0-9,20-24,28-39,41-99,220-255";
+       char *prop_name = "msi-available-ranges";
+       char *node_name = "/fakenode";
+       struct device_node of_node;
+       struct property prop;
+       struct msi_bitmap bmp;
+       int size = 256;
+       DECLARE_BITMAP(expected, size);
+
+       /* There should really be a struct device_node allocator */
+       memset(&of_node, 0, sizeof(of_node));
+       kref_init(&of_node.kref);
+       of_node.full_name = node_name;
+
+       check(0 == msi_bitmap_alloc(&bmp, size, &of_node));
+
+       /* No msi-available-ranges, so expect > 0 */
+       check(msi_bitmap_reserve_dt_hwirqs(&bmp) > 0);
+
+       /* Should all still be free */
+       check(0 == bitmap_find_free_region(bmp.bitmap, size,
+                                          get_count_order(size)));
+       bitmap_release_region(bmp.bitmap, 0, get_count_order(size));
+
+       /* Now create a fake msi-available-ranges property */
+
+       /* There should really .. oh whatever */
+       memset(&prop, 0, sizeof(prop));
+       prop.name = prop_name;
+       prop.value = &prop_data;
+       prop.length = sizeof(prop_data);
+
+       of_node.properties = &prop;
+
+       /* msi-available-ranges, so expect == 0 */
+       check(msi_bitmap_reserve_dt_hwirqs(&bmp) == 0);
+
+       /* Check we got the expected result */
+       check(0 == bitmap_parselist(expected_str, expected, size));
+       check(bitmap_equal(expected, bmp.bitmap, size));
+
+       msi_bitmap_free(&bmp);
+       kfree(bmp.bitmap);
+}
+
+int msi_bitmap_selftest(void)
+{
+       printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n");
+
+       test_basics();
+       test_of_node();
+
+       return 0;
+}
+late_initcall(msi_bitmap_selftest);
+#endif /* CONFIG_MSI_BITMAP_SELFTEST */
index e8a76d9539dbb82e7aed662a19a6c0f71aa8b27e..d3e4d61030b59039759ad4d4d2eaa9318e32abe0 100644 (file)
 #include <asm/machdep.h>
 #include <asm/dcr.h>
 #include <asm/dcr-regs.h>
+#include <mm/mmu_decl.h>
 
 #include "ppc4xx_pci.h"
 
 static int dma_offset_set;
 
-/* Move that to a useable header */
-extern unsigned long total_memory;
-
 #define U64_TO_U32_LOW(val)    ((u32)((val) & 0x00000000ffffffffULL))
 #define U64_TO_U32_HIGH(val)   ((u32)((val) >> 32))
 
@@ -102,7 +100,8 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
 
        /* Default */
        res->start = 0;
-       res->end = size = 0x80000000;
+       size = 0x80000000;
+       res->end = size - 1;
        res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
 
        /* Get dma-ranges property */
@@ -163,13 +162,13 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
         */
        if (size < total_memory) {
                printk(KERN_ERR "%s: dma-ranges too small "
-                      "(size=%llx total_memory=%lx)\n",
-                      hose->dn->full_name, size, total_memory);
+                      "(size=%llx total_memory=%llx)\n",
+                      hose->dn->full_name, size, (u64)total_memory);
                return -ENXIO;
        }
 
        /* Check we are a power of 2 size and that base is a multiple of size*/
-       if (!is_power_of_2(size) ||
+       if ((size & (size - 1)) != 0  ||
            (res->start & (size - 1)) != 0) {
                printk(KERN_ERR "%s: dma-ranges unaligned\n",
                       hose->dn->full_name);
@@ -273,9 +272,16 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
        const int *bus_range;
        int primary = 0;
 
+       /* Check if device is enabled */
+       if (!of_device_is_available(np)) {
+               printk(KERN_INFO "%s: Port disabled via device-tree\n",
+                      np->full_name);
+               return;
+       }
+
        /* Fetch config space registers address */
        if (of_address_to_resource(np, 0, &rsrc_cfg)) {
-               printk(KERN_ERR "%s:Can't get PCI config register base !",
+               printk(KERN_ERR "%s: Can't get PCI config register base !",
                       np->full_name);
                return;
        }
@@ -806,7 +812,7 @@ static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
        switch (port->index) {
        case 0:
                mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230);
-               mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000136);
+               mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
                mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
 
                mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST,0x10000000);
@@ -817,10 +823,10 @@ static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
                mtdcri(SDR0, PESDR1_460EX_L1CDRCTL, 0x00003230);
                mtdcri(SDR0, PESDR1_460EX_L2CDRCTL, 0x00003230);
                mtdcri(SDR0, PESDR1_460EX_L3CDRCTL, 0x00003230);
-               mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000136);
-               mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000136);
-               mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000136);
-               mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000136);
+               mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000130);
+               mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000130);
+               mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000130);
+               mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000130);
                mtdcri(SDR0, PESDR1_460EX_L0CLK, 0x00000006);
                mtdcri(SDR0, PESDR1_460EX_L1CLK, 0x00000006);
                mtdcri(SDR0, PESDR1_460EX_L2CLK, 0x00000006);
index 1ce546462be5af559539fb00314c8fc89d0c03b1..76ffbc48d4b949f410e611b15d6550a647bdb30b 100644 (file)
@@ -24,12 +24,3 @@ config QE_USB
        bool
        help
          QE USB Host Controller support
-
-config QE_GPIO
-       bool "QE GPIO support"
-       depends on QUICC_ENGINE
-       select GENERIC_GPIO
-       select ARCH_REQUIRE_GPIOLIB
-       help
-         Say Y here if you're going to use hardware that connects to the
-         QE GPIOs.
index 3cad56923815156107862b27e69bb4b2648b5ad8..261785ab5b2248f41e274fb8ec93d03e0f4d2f76 100644 (file)
@@ -166,13 +166,11 @@ extern char elf_platform[];
 #define ELF_PLATFORM (elf_platform)
 
 #ifndef __s390x__
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 #else /* __s390x__ */
-#define SET_PERSONALITY(ex, ibcs2)                     \
+#define SET_PERSONALITY(ex)                            \
 do {                                                   \
-       if (ibcs2)                                      \
-               set_personality(PER_SVR4);              \
-       else if (current->personality != PER_LINUX32)   \
+       if (current->personality != PER_LINUX32)        \
                set_personality(PER_LINUX);             \
        if ((ex).e_ident[EI_CLASS] == ELFCLASS32)       \
                set_thread_flag(TIF_31BIT);             \
index 98e246dc02338bef90d6cd9f27d39069b4cac414..4646382af34f1260a547274d69c4341852fb55fb 100644 (file)
@@ -279,22 +279,6 @@ asmlinkage long sys32_getegid16(void)
        return high2lowgid(current->egid);
 }
 
-/* 32-bit timeval and related flotsam.  */
-
-static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) ||
-                __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) ||
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
 /*
  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.
  *
@@ -362,41 +346,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
                return sys_ftruncate(fd, (high << 32) | low);
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
-       compat_ino_t ino;
-       int err;
-
-       if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
-               return -EOVERFLOW;
-
-       ino = stat->ino;
-       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
-               return -EOVERFLOW;
-
-       err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
-       err |= put_user(stat->ino, &statbuf->st_ino);
-       err |= put_user(stat->mode, &statbuf->st_mode);
-       err |= put_user(stat->nlink, &statbuf->st_nlink);
-       err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
-       err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
-       err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
-       err |= put_user(stat->size, &statbuf->st_size);
-       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-       err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-       err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-       err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-       err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-       err |= put_user(stat->blksize, &statbuf->st_blksize);
-       err |= put_user(stat->blocks, &statbuf->st_blocks);
-/* fixme
-       err |= put_user(0, &statbuf->__unused4[0]);
-       err |= put_user(0, &statbuf->__unused4[1]);
-*/
-       return err;
-}
-
 asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid,
                                struct compat_timespec __user *interval)
 {
@@ -557,57 +506,6 @@ sys32_delete_module(const char __user *name_user, unsigned int flags)
 
 #endif  /* CONFIG_MODULES */
 
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-
-extern struct timezone sys_tz;
-
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
index 05f8516366ab0df450c12a53723a53fe94ef841e..836a28842900eee9b6c6e1f038a9a6d124e55707 100644 (file)
@@ -202,10 +202,6 @@ long sys32_execve(void);
 long sys32_init_module(void __user *umod, unsigned long len,
                       const char __user *uargs);
 long sys32_delete_module(const char __user *name_user, unsigned int flags);
-long sys32_gettimeofday(struct compat_timeval __user *tv,
-                       struct timezone __user *tz);
-long sys32_settimeofday(struct compat_timeval __user *tv,
-                       struct timezone __user *tz);
 long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count,
                   u32 poshi, u32 poslo);
 long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
index ee51ca9e23b56e1ba0380323f4cac8193d63c627..fc2c97197a53ffbe9df9917e7087de4ecb1a57d9 100644 (file)
@@ -332,17 +332,17 @@ compat_sys_getrusage_wrapper:
        llgtr   %r3,%r3                 # struct rusage_emu31 *
        jg      compat_sys_getrusage    # branch to system call
 
-       .globl  sys32_gettimeofday_wrapper
-sys32_gettimeofday_wrapper:
+       .globl  compat_sys_gettimeofday_wrapper
+compat_sys_gettimeofday_wrapper:
        llgtr   %r2,%r2                 # struct timeval_emu31 *
        llgtr   %r3,%r3                 # struct timezone *
-       jg      sys32_gettimeofday      # branch to system call
+       jg      compat_sys_gettimeofday # branch to system call
 
-       .globl  sys32_settimeofday_wrapper
-sys32_settimeofday_wrapper:
+       .globl  compat_sys_settimeofday_wrapper
+compat_sys_settimeofday_wrapper:
        llgtr   %r2,%r2                 # struct timeval_emu31 *
        llgtr   %r3,%r3                 # struct timezone *
-       jg      sys32_settimeofday      # branch to system call
+       jg      compat_sys_settimeofday # branch to system call
 
        .globl  sys32_getgroups16_wrapper
 sys32_getgroups16_wrapper:
index 3ae303914b4201f63dc83c09ca74744e2e3ec283..2d61787949d5b9ee99b7512373668131ad7da7b4 100644 (file)
@@ -86,8 +86,8 @@ SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper)
 SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper)      /* 75 */
 SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper)
 SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage_wrapper)
-SYSCALL(sys_gettimeofday,sys_gettimeofday,sys32_gettimeofday_wrapper)
-SYSCALL(sys_settimeofday,sys_settimeofday,sys32_settimeofday_wrapper)
+SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper)
+SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper)
 SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper)      /* 80 old getgroups16 syscall */
 SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper)      /* old setgroups16 syscall */
 NI_SYSCALL                                                     /* old select syscall */
index f01449a8d378c498197150df82abf6ab8b439b09..ee02db110f0da3b78aa0c5a4c66ba13c28c362a3 100644 (file)
@@ -189,7 +189,7 @@ do {                                                                        \
 } while (0)
 #endif
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
 struct task_struct;
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
index b7ab605478270779478103013c5fca34ea55f3f4..381a1b5256d6c9f23e0cb683b90ba8307265a409 100644 (file)
@@ -137,6 +137,6 @@ typedef struct {
 
 #define ELF_PLATFORM   (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif /* !(__ASMSPARC_ELF_H) */
index 0818a1308f4e7a252b213d07a0025f5e70c72dca..425c2f9be6d5abe1e5e9aa53a157440807817838 100644 (file)
@@ -195,7 +195,7 @@ static inline unsigned int sparc64_elf_hwcap(void)
 
 #define ELF_PLATFORM   (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2)                     \
+#define SET_PERSONALITY(ex)                            \
 do {   unsigned long new_flags = current_thread_info()->flags; \
        new_flags &= _TIF_32BIT;                        \
        if ((ex).e_ident[EI_CLASS] == ELFCLASS32)       \
@@ -208,9 +208,7 @@ do {        unsigned long new_flags = current_thread_info()->flags; \
        else                                            \
                clear_thread_flag(TIF_ABI_PENDING);     \
        /* flush_thread will update pgd cache */        \
-       if (ibcs2)                                      \
-               set_personality(PER_SVR4);              \
-       else if (current->personality != PER_LINUX32)   \
+       if (current->personality != PER_LINUX32)        \
                set_personality(PER_LINUX);             \
 } while (0)
 
index 2a37a6ca2a16d46e5dd5ea5680230b56e11bedb3..1cc1995531e22d3f7e5066fadd2fc66df16e3a63 100644 (file)
@@ -575,7 +575,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
                }
                /* Allocate iommu entries for that segment */
                paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
-               npages = iommu_num_pages(paddr, slen);
+               npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE);
                entry = iommu_range_alloc(dev, iommu, npages, &handle);
 
                /* Handle failure */
@@ -647,7 +647,8 @@ iommu_map_failed:
                        iopte_t *base;
 
                        vaddr = s->dma_address & IO_PAGE_MASK;
-                       npages = iommu_num_pages(s->dma_address, s->dma_length);
+                       npages = iommu_num_pages(s->dma_address, s->dma_length,
+                                                IO_PAGE_SIZE);
                        iommu_range_free(iommu, vaddr, npages);
 
                        entry = (vaddr - iommu->page_table_map_base)
@@ -715,7 +716,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
 
                if (!len)
                        break;
-               npages = iommu_num_pages(dma_handle, len);
+               npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE);
                iommu_range_free(iommu, dma_handle, npages);
 
                entry = ((dma_handle - iommu->page_table_map_base)
index 53b19c8231a931ee1ab2f1a863e62053026ac748..591f5879039ce316a2a9d5187af3367f46e86ecb 100644 (file)
 
 #define SG_ENT_PHYS_ADDRESS(SG)        (__pa(sg_virt((SG))))
 
-static inline unsigned long iommu_num_pages(unsigned long vaddr,
-                                           unsigned long slen)
-{
-       unsigned long npages;
-
-       npages = IO_PAGE_ALIGN(vaddr + slen) - (vaddr & IO_PAGE_MASK);
-       npages >>= IO_PAGE_SHIFT;
-
-       return npages;
-}
-
 static inline int is_span_boundary(unsigned long entry,
                                   unsigned long shift,
                                   unsigned long boundary_size,
@@ -53,7 +42,8 @@ static inline int is_span_boundary(unsigned long entry,
                                   struct scatterlist *sg)
 {
        unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
-       int nr = iommu_num_pages(paddr, outs->dma_length + sg->length);
+       int nr = iommu_num_pages(paddr, outs->dma_length + sg->length,
+                                IO_PAGE_SIZE);
 
        return iommu_is_span_boundary(entry, nr, shift, boundary_size);
 }
index e86c73ec167b3ff66d887204f41630d71e7f2d08..34a1fded39415cbbc863f39babe56bacd39d489a 100644 (file)
@@ -384,7 +384,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
                }
                /* Allocate iommu entries for that segment */
                paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
-               npages = iommu_num_pages(paddr, slen);
+               npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE);
                entry = iommu_range_alloc(dev, iommu, npages, &handle);
 
                /* Handle failure */
@@ -461,7 +461,8 @@ iommu_map_failed:
                        unsigned long vaddr, npages;
 
                        vaddr = s->dma_address & IO_PAGE_MASK;
-                       npages = iommu_num_pages(s->dma_address, s->dma_length);
+                       npages = iommu_num_pages(s->dma_address, s->dma_length,
+                                                IO_PAGE_SIZE);
                        iommu_range_free(iommu, vaddr, npages);
                        /* XXX demap? XXX */
                        s->dma_address = DMA_ERROR_CODE;
@@ -500,7 +501,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
 
                if (!len)
                        break;
-               npages = iommu_num_pages(dma_handle, len);
+               npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE);
                iommu_range_free(iommu, dma_handle, npages);
 
                entry = ((dma_handle - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
index 3320c9d0075f79eac52690def1371024d1b3f9bb..e800503879e4b6dc410eecd74ee2d2138d742083 100644 (file)
 #include <asm/mmu_context.h>
 #include <asm/compat_signal.h>
 
-/* 32-bit timeval and related flotsam.  */
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-               (__put_user(i->tv_sec, &o->tv_sec) |
-                __put_user(i->tv_usec, &o->tv_usec)));
-}
-
 #ifdef CONFIG_SYSVIPC                                                        
 asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth)
 {
@@ -148,41 +139,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
                return sys_ftruncate(fd, (high << 32) | low);
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
-       compat_ino_t ino;
-       int err;
-
-       if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
-           !old_valid_dev(stat->rdev))
-               return -EOVERFLOW;
-
-       ino = stat->ino;
-       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
-               return -EOVERFLOW;
-
-       err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
-       err |= put_user(stat->ino, &statbuf->st_ino);
-       err |= put_user(stat->mode, &statbuf->st_mode);
-       err |= put_user(stat->nlink, &statbuf->st_nlink);
-       err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
-       err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
-       err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
-       err |= put_user(stat->size, &statbuf->st_size);
-       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
-       err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-       err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
-       err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-       err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
-       err |= put_user(stat->blksize, &statbuf->st_blksize);
-       err |= put_user(stat->blocks, &statbuf->st_blocks);
-       err |= put_user(0, &statbuf->__unused4[0]);
-       err |= put_user(0, &statbuf->__unused4[1]);
-
-       return err;
-}
-
 static int cp_compat_stat64(struct kstat *stat,
                            struct compat_stat64 __user *statbuf)
 {
@@ -522,59 +478,6 @@ asmlinkage long sys32_delete_module(const char __user *name_user)
 
 #endif  /* CONFIG_MODULES */
 
-/* Translations due to time_t size differences.  Which affects all
-   sorts of things, like timeval and itimerval.  */
-
-extern struct timezone sys_tz;
-
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
-       long usec;
-
-       if (!access_ok(VERIFY_READ, i, sizeof(*i)))
-               return -EFAULT;
-       if (__get_user(o->tv_sec, &i->tv_sec))
-               return -EFAULT;
-       if (__get_user(usec, &i->tv_usec))
-               return -EFAULT;
-       o->tv_nsec = usec * 1000;
-       return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_ts32(&kts, tv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
                                        char __user *ubuf,
                                        compat_size_t count,
index 5daee4b04dd5a655c313c07ee1dabf4ea34871fe..b2fa4c1636387f2e40bf52a09c8d80bae7dce36c 100644 (file)
@@ -41,8 +41,8 @@ sys_call_table32:
 /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
        .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
 /*110*/        .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
-       .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
-/*120*/        .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys_fchown16, sys_fchmod
+       .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
+/*120*/        .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
        .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
 /*130*/        .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
        .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
index 47e3acafb5be4c0f0786bbe12fd2b353334f4d92..365b6464e2ce20037e27af6023aa330ba6380612 100644 (file)
@@ -183,7 +183,6 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
        table[3].index = 0;
        table[3].frequency = CPUFREQ_TABLE_END;
 
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        policy->cpuinfo.transition_latency = 0;
        policy->cur = clock_tick;
 
index f5d7f4569ba726f51fc92ef1b3b7e0ccdcb4e230..598711c62c82cbb59ce79193eaa67e70d45b48e3 100644 (file)
@@ -42,23 +42,11 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
        PT_REGS_SP(regs) = esp;
 }
 
-#ifdef CONFIG_TTY_LOG
-extern void log_exec(char **argv, void *tty);
-#endif
-
 static long execve1(char *file, char __user * __user *argv,
                    char __user *__user *env)
 {
        long error;
-#ifdef CONFIG_TTY_LOG
-       struct tty_struct *tty;
 
-       mutex_lock(&tty_mutex);
-       tty = get_current_tty();
-       if (tty)
-               log_exec(argv, tty);
-       mutex_unlock(&tty_mutex);
-#endif
        error = do_execve(file, argv, env, &current->thread.regs);
        if (error == 0) {
                task_lock(current);
index 8a48d6a30064139fa28bcfc53a0897b046988a3b..d66f0388f091f17e0b7d06257853bc9b2e3b1859 100644 (file)
@@ -7,9 +7,6 @@ obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
        registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \
        umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
 
-obj-$(CONFIG_TTY_LOG) += tty_log.o
-user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-
 USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
        main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
        tty.o tls.o uaccess.o umid.o util.o
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
deleted file mode 100644 (file)
index cc648e6..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
- * geoffrey hing <ghing@net.ohio-state.edu>
- * Licensed under the GPL
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "init.h"
-#include "user.h"
-#include "os.h"
-
-#define TTY_LOG_DIR "./"
-
-/* Set early in boot and then unchanged */
-static char *tty_log_dir = TTY_LOG_DIR;
-static int tty_log_fd = -1;
-
-#define TTY_LOG_OPEN 1
-#define TTY_LOG_CLOSE 2
-#define TTY_LOG_WRITE 3
-#define TTY_LOG_EXEC 4
-
-#define TTY_READ 1
-#define TTY_WRITE 2
-
-struct tty_log_buf {
-       int what;
-       unsigned long tty;
-       int len;
-       int direction;
-       unsigned long sec;
-       unsigned long usec;
-};
-
-int open_tty_log(void *tty, void *current_tty)
-{
-       struct timeval tv;
-       struct tty_log_buf data;
-       char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
-       int fd;
-
-       gettimeofday(&tv, NULL);
-       if(tty_log_fd != -1){
-               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
-                                              .tty  = (unsigned long) tty,
-                                              .len  = sizeof(current_tty),
-                                              .direction = 0,
-                                              .sec = tv.tv_sec,
-                                              .usec = tv.tv_usec } );
-               write(tty_log_fd, &data, sizeof(data));
-               write(tty_log_fd, &current_tty, data.len);
-               return tty_log_fd;
-       }
-
-       sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
-               (unsigned int) tv.tv_usec);
-
-       fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
-                         0644);
-       if(fd < 0){
-               printk("open_tty_log : couldn't open '%s', errno = %d\n",
-                      buf, -fd);
-       }
-       return fd;
-}
-
-void close_tty_log(int fd, void *tty)
-{
-       struct tty_log_buf data;
-       struct timeval tv;
-
-       if(tty_log_fd != -1){
-               gettimeofday(&tv, NULL);
-               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
-                                              .tty  = (unsigned long) tty,
-                                              .len  = 0,
-                                              .direction = 0,
-                                              .sec = tv.tv_sec,
-                                              .usec = tv.tv_usec } );
-               write(tty_log_fd, &data, sizeof(data));
-               return;
-       }
-       os_close_file(fd);
-}
-
-static int log_chunk(int fd, const char *buf, int len)
-{
-       int total = 0, try, missed, n;
-       char chunk[64];
-
-       while(len > 0){
-               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
-               missed = copy_from_user_proc(chunk, (char *) buf, try);
-               try -= missed;
-               n = write(fd, chunk, try);
-               if(n != try) {
-                       if(n < 0)
-                               return -errno;
-                       return -EIO;
-               }
-               if(missed != 0)
-                       return -EFAULT;
-
-               len -= try;
-               total += try;
-               buf += try;
-       }
-
-       return total;
-}
-
-int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
-{
-       struct timeval tv;
-       struct tty_log_buf data;
-       int direction;
-
-       if(fd == tty_log_fd){
-               gettimeofday(&tv, NULL);
-               direction = is_read ? TTY_READ : TTY_WRITE;
-               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
-                                              .tty  = (unsigned long) tty,
-                                              .len  = len,
-                                              .direction = direction,
-                                              .sec = tv.tv_sec,
-                                              .usec = tv.tv_usec } );
-               write(tty_log_fd, &data, sizeof(data));
-       }
-
-       return log_chunk(fd, buf, len);
-}
-
-void log_exec(char **argv, void *tty)
-{
-       struct timeval tv;
-       struct tty_log_buf data;
-       char **ptr,*arg;
-       int len;
-
-       if(tty_log_fd == -1) return;
-
-       gettimeofday(&tv, NULL);
-
-       len = 0;
-       for(ptr = argv; ; ptr++){
-               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
-                       return;
-               if(arg == NULL) break;
-               len += strlen_user_proc(arg);
-       }
-
-       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
-                                      .tty  = (unsigned long) tty,
-                                      .len  = len,
-                                      .direction = 0,
-                                      .sec = tv.tv_sec,
-                                      .usec = tv.tv_usec } );
-       write(tty_log_fd, &data, sizeof(data));
-
-       for(ptr = argv; ; ptr++){
-               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
-                       return;
-               if(arg == NULL) break;
-               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
-       }
-}
-
-extern void register_tty_logger(int (*opener)(void *, void *),
-                               int (*writer)(int, const char *, int,
-                                             void *, int),
-                               void (*closer)(int, void *));
-
-static int register_logger(void)
-{
-       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
-       return 0;
-}
-
-__uml_initcall(register_logger);
-
-static int __init set_tty_log_dir(char *name, int *add)
-{
-       tty_log_dir = name;
-       return 0;
-}
-
-__uml_setup("tty_log_dir=", set_tty_log_dir,
-"tty_log_dir=<directory>\n"
-"    This is used to specify the directory where the logs of all pty\n"
-"    data from this UML machine will be written.\n\n"
-);
-
-static int __init set_tty_log_fd(char *name, int *add)
-{
-       char *end;
-
-       tty_log_fd = strtoul(name, &end, 0);
-       if((*end != '\0') || (end == name)){
-               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
-               tty_log_fd = -1;
-       }
-
-       *add = 0;
-       return 0;
-}
-
-__uml_setup("tty_log_fd=", set_tty_log_fd,
-"tty_log_fd=<fd>\n"
-"    This is used to specify a preconfigured file descriptor to which all\n"
-"    tty data will be written.  Preconfigure the descriptor with something\n"
-"    like '10>tty_log tty_log_fd=10'.\n\n"
-);
index 837a9aae0453f554fa89d60dc42875aa5fff81bc..bd3c2c53873ecb4cd0b944e31996b746884d6cf0 100644 (file)
@@ -39,10 +39,6 @@ config ARCH_DEFCONFIG
        default "arch/x86/configs/i386_defconfig" if X86_32
        default "arch/x86/configs/x86_64_defconfig" if X86_64
 
-
-config GENERIC_LOCKBREAK
-       def_bool n
-
 config GENERIC_TIME
        def_bool y
 
@@ -95,7 +91,7 @@ config GENERIC_HWEIGHT
        def_bool y
 
 config GENERIC_GPIO
-       def_bool n
+       bool
 
 config ARCH_MAY_HAVE_PC_FDC
        def_bool y
@@ -106,12 +102,6 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        def_bool X86_XADD
 
-config ARCH_HAS_ILOG2_U32
-       def_bool n
-
-config ARCH_HAS_ILOG2_U64
-       def_bool n
-
 config ARCH_HAS_CPU_IDLE_WAIT
        def_bool y
 
@@ -758,9 +748,8 @@ config I8K
          Say N otherwise.
 
 config X86_REBOOTFIXUPS
-       def_bool n
-       prompt "Enable X86 board specific fixups for reboot"
-       depends on X86_32 && X86
+       bool "Enable X86 board specific fixups for reboot"
+       depends on X86_32
        ---help---
          This enables chipset and/or board specific fixups to be done
          in order to get reboot to work correctly. This is only needed on
@@ -944,8 +933,7 @@ config HIGHMEM
        depends on X86_32 && (HIGHMEM64G || HIGHMEM4G)
 
 config X86_PAE
-       def_bool n
-       prompt "PAE (Physical Address Extension) Support"
+       bool "PAE (Physical Address Extension) Support"
        depends on X86_32 && !HIGHMEM4G
        help
          PAE is required for NX support, and furthermore enables
@@ -1240,8 +1228,7 @@ config X86_PAT
          If unsure, say Y.
 
 config EFI
-       def_bool n
-       prompt "EFI runtime service support"
+       bool "EFI runtime service support"
        depends on ACPI
        ---help---
        This enables the kernel to use EFI runtime services that are
index 1e6fe0214c85a34788f8ddb55f3d9b3f559b0f41..99b3079dc6ab1fb25c4f083639b13547fa663354 100644 (file)
@@ -88,14 +88,11 @@ static int vesa_probe(void)
                           (vminfo.memory_layout == 4 ||
                            vminfo.memory_layout == 6) &&
                           vminfo.memory_planes == 1) {
-#ifdef CONFIG_FB
+#ifdef CONFIG_FB_BOOT_VESA_SUPPORT
                        /* Graphics mode, color, linear frame buffer
                           supported.  Only register the mode if
                           if framebuffer is configured, however,
-                          otherwise the user will be left without a screen.
-                          We don't require CONFIG_FB_VESA, however, since
-                          some of the other framebuffer drivers can use
-                          this mode-setting, too. */
+                          otherwise the user will be left without a screen. */
                        mi = GET_HEAP(struct mode_info, 1);
                        mi->mode = mode + VIDEO_FIRST_VESA;
                        mi->depth = vminfo.bpp;
@@ -133,10 +130,12 @@ static int vesa_set_mode(struct mode_info *mode)
        if ((vminfo.mode_attr & 0x15) == 0x05) {
                /* It's a supported text mode */
                is_graphic = 0;
+#ifdef CONFIG_FB_BOOT_VESA_SUPPORT
        } else if ((vminfo.mode_attr & 0x99) == 0x99) {
                /* It's a graphics mode with linear frame buffer */
                is_graphic = 1;
                vesa_mode |= 0x4000; /* Request linear frame buffer */
+#endif
        } else {
                return -1;      /* Invalid mode */
        }
index eb4314768bf7ad7f14e8589fe66876a99dc52b8c..256b00b61892b2e3049ef8ff65a672df701efc77 100644 (file)
@@ -571,8 +571,8 @@ ia32_sys_call_table:
        .quad compat_sys_setrlimit      /* 75 */
        .quad compat_sys_old_getrlimit  /* old_getrlimit */
        .quad compat_sys_getrusage
-       .quad sys32_gettimeofday
-       .quad sys32_settimeofday
+       .quad compat_sys_gettimeofday
+       .quad compat_sys_settimeofday
        .quad sys_getgroups16   /* 80 */
        .quad sys_setgroups16
        .quad sys32_old_select
index beda4232ce695cc2f42aea28dea84dad02a38235..2e09dcd3c0a6034d46e3345efa40736e49941d13 100644 (file)
 
 #define AA(__x)                ((unsigned long)(__x))
 
-int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
-{
-       compat_ino_t ino;
-
-       typeof(ubuf->st_uid) uid = 0;
-       typeof(ubuf->st_gid) gid = 0;
-       SET_UID(uid, kbuf->uid);
-       SET_GID(gid, kbuf->gid);
-       if (!old_valid_dev(kbuf->dev) || !old_valid_dev(kbuf->rdev))
-               return -EOVERFLOW;
-       if (kbuf->size >= 0x7fffffff)
-               return -EOVERFLOW;
-       ino = kbuf->ino;
-       if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
-               return -EOVERFLOW;
-       if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
-           __put_user(old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
-           __put_user(ino, &ubuf->st_ino) ||
-           __put_user(kbuf->mode, &ubuf->st_mode) ||
-           __put_user(kbuf->nlink, &ubuf->st_nlink) ||
-           __put_user(uid, &ubuf->st_uid) ||
-           __put_user(gid, &ubuf->st_gid) ||
-           __put_user(old_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
-           __put_user(kbuf->size, &ubuf->st_size) ||
-           __put_user(kbuf->atime.tv_sec, &ubuf->st_atime) ||
-           __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
-           __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime) ||
-           __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
-           __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime) ||
-           __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
-           __put_user(kbuf->blksize, &ubuf->st_blksize) ||
-           __put_user(kbuf->blocks, &ubuf->st_blocks))
-               return -EFAULT;
-       return 0;
-}
 
 asmlinkage long sys32_truncate64(char __user *filename,
                                 unsigned long offset_low,
@@ -402,75 +367,11 @@ asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
        return 0;
 }
 
-static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       int err = -EFAULT;
-
-       if (access_ok(VERIFY_READ, i, sizeof(*i))) {
-               err = __get_user(o->tv_sec, &i->tv_sec);
-               err |= __get_user(o->tv_usec, &i->tv_usec);
-       }
-       return err;
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
-       int err = -EFAULT;
-
-       if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
-               err = __put_user(i->tv_sec, &o->tv_sec);
-               err |= __put_user(i->tv_usec, &o->tv_usec);
-       }
-       return err;
-}
-
 asmlinkage long sys32_alarm(unsigned int seconds)
 {
        return alarm_setitimer(seconds);
 }
 
-/*
- * Translations due to time_t size differences. Which affects all
- * sorts of things, like timeval and itimerval.
- */
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       if (tv) {
-               struct timeval ktv;
-
-               do_gettimeofday(&ktv);
-               if (put_tv32(tv, &ktv))
-                       return -EFAULT;
-       }
-       if (tz) {
-               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
-                       return -EFAULT;
-       }
-       return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
-                                  struct timezone __user *tz)
-{
-       struct timeval ktv;
-       struct timespec kts;
-       struct timezone ktz;
-
-       if (tv) {
-               if (get_tv32(&ktv, tv))
-                       return -EFAULT;
-               kts.tv_sec = ktv.tv_sec;
-               kts.tv_nsec = ktv.tv_usec * NSEC_PER_USEC;
-       }
-       if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
-                       return -EFAULT;
-       }
-
-       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
 struct sel_arg_struct {
        unsigned int n;
        unsigned int inp;
index 34e4d112b1ef1bf54720a17f71756f8dd1394dfa..a8fd9ebdc8e25232e66b4d28a10edc0a70b8b151 100644 (file)
@@ -295,7 +295,7 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
                u64 address, size_t size)
 {
        int s = 0;
-       unsigned pages = iommu_num_pages(address, size);
+       unsigned pages = iommu_num_pages(address, size, PAGE_SIZE);
 
        address &= PAGE_MASK;
 
@@ -680,7 +680,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
            iommu->exclusion_start < dma_dom->aperture_size) {
                unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
                int pages = iommu_num_pages(iommu->exclusion_start,
-                                           iommu->exclusion_length);
+                                           iommu->exclusion_length,
+                                           PAGE_SIZE);
                dma_ops_reserve_addresses(dma_dom, startpage, pages);
        }
 
@@ -935,7 +936,7 @@ static dma_addr_t __map_single(struct device *dev,
        unsigned long align_mask = 0;
        int i;
 
-       pages = iommu_num_pages(paddr, size);
+       pages = iommu_num_pages(paddr, size, PAGE_SIZE);
        paddr &= PAGE_MASK;
 
        if (align)
@@ -980,7 +981,7 @@ static void __unmap_single(struct amd_iommu *iommu,
        if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size))
                return;
 
-       pages = iommu_num_pages(dma_addr, size);
+       pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
        dma_addr &= PAGE_MASK;
        start = dma_addr;
 
index 6a44d646599156cc5910cce8f503832688c973a5..72cefd1e649ba4be254b5ec497f442160dab1752 100644 (file)
@@ -147,8 +147,8 @@ static __cpuinit int cpuid_device_create(int cpu)
 {
        struct device *dev;
 
-       dev = device_create_drvdata(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
-                                   NULL, "cpu%d", cpu);
+       dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
+                           "cpu%d", cpu);
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 
index 201ee359a1a98c2d33049b4325da5a86d5b68fda..1a78180f08d39aa2a87a2b2738e7a6b488a4d5dc 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kexec.h>
 #include <linux/bug.h>
 #include <linux/nmi.h>
+#include <linux/sysfs.h>
 
 #include <asm/stacktrace.h>
 
@@ -343,6 +344,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
        printk("DEBUG_PAGEALLOC");
 #endif
        printk("\n");
+       sysfs_printk_last_file();
        if (notify_die(DIE_OOPS, str, regs, err,
                        current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
                return 1;
index 086cc8118e391e00b196ddf5dd53f285643f5789..96a5db7da8a747e5192f410c60fe9494e8d8e8d1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kexec.h>
 #include <linux/bug.h>
 #include <linux/nmi.h>
+#include <linux/sysfs.h>
 
 #include <asm/stacktrace.h>
 
@@ -489,6 +490,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
        printk("DEBUG_PAGEALLOC");
 #endif
        printk("\n");
+       sysfs_printk_last_file();
        if (notify_die(DIE_OOPS, str, regs, err,
                        current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
                return 1;
index 2e2af5d1819160c6047b82a06b6f141e5a23f39c..82a7c7ed6d456401ef1776a53030a4db7890443e 100644 (file)
@@ -163,8 +163,8 @@ static int __cpuinit msr_device_create(int cpu)
 {
        struct device *dev;
 
-       dev = device_create_drvdata(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
-                                   NULL, "msr%d", cpu);
+       dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
+                           "msr%d", cpu);
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 
index 080d1d27f37a0b4e042c6623af4cbf0c9ff5e8e7..e1e731d78f3821bb6f27950eca4033e52a77c606 100644 (file)
@@ -217,16 +217,6 @@ static inline unsigned long verify_bit_range(unsigned long* bitmap,
 
 #endif /* CONFIG_IOMMU_DEBUG */
 
-static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
-{
-       unsigned int npages;
-
-       npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK);
-       npages >>= PAGE_SHIFT;
-
-       return npages;
-}
-
 static inline int translation_enabled(struct iommu_table *tbl)
 {
        /* only PHBs with translation enabled have an IOMMU table */
@@ -408,7 +398,7 @@ static void calgary_unmap_sg(struct device *dev,
                if (dmalen == 0)
                        break;
 
-               npages = num_dma_pages(dma, dmalen);
+               npages = iommu_num_pages(dma, dmalen, PAGE_SIZE);
                iommu_free(tbl, dma, npages);
        }
 }
@@ -427,7 +417,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
                BUG_ON(!sg_page(s));
 
                vaddr = (unsigned long) sg_virt(s);
-               npages = num_dma_pages(vaddr, s->length);
+               npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE);
 
                entry = iommu_range_alloc(dev, tbl, npages);
                if (entry == bad_dma_address) {
@@ -464,7 +454,7 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr,
        struct iommu_table *tbl = find_iommu_table(dev);
 
        uaddr = (unsigned long)vaddr;
-       npages = num_dma_pages(uaddr, size);
+       npages = iommu_num_pages(uaddr, size, PAGE_SIZE);
 
        return iommu_alloc(dev, tbl, vaddr, npages, direction);
 }
@@ -475,7 +465,7 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
        struct iommu_table *tbl = find_iommu_table(dev);
        unsigned int npages;
 
-       npages = num_dma_pages(dma_handle, size);
+       npages = iommu_num_pages(dma_handle, size, PAGE_SIZE);
        iommu_free(tbl, dma_handle, npages);
 }
 
index 0a3824e837b4c1b38d3fdc6b778e4d6ba076f4bc..192624820217f9eeeb64ee39ada5ad57a76a0df5 100644 (file)
@@ -125,13 +125,13 @@ void __init pci_iommu_alloc(void)
        pci_swiotlb_init();
 }
 
-unsigned long iommu_num_pages(unsigned long addr, unsigned long len)
+unsigned long iommu_nr_pages(unsigned long addr, unsigned long len)
 {
        unsigned long size = roundup((addr & ~PAGE_MASK) + len, PAGE_SIZE);
 
        return size >> PAGE_SHIFT;
 }
-EXPORT_SYMBOL(iommu_num_pages);
+EXPORT_SYMBOL(iommu_nr_pages);
 #endif
 
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
index 145f1c83369f17a7e5696a7e241d1d28573606dc..e3f75bbcedea9287d8941897004e25159b3e9796 100644 (file)
@@ -231,7 +231,7 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
 static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
                                size_t size, int dir, unsigned long align_mask)
 {
-       unsigned long npages = iommu_num_pages(phys_mem, size);
+       unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE);
        unsigned long iommu_page = alloc_iommu(dev, npages, align_mask);
        int i;
 
@@ -285,7 +285,7 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
                return;
 
        iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
-       npages = iommu_num_pages(dma_addr, size);
+       npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
        for (i = 0; i < npages; i++) {
                iommu_gatt_base[iommu_page + i] = gart_unmapped_entry;
                CLEAR_LEAK(iommu_page + i);
@@ -368,7 +368,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
                }
 
                addr = phys_addr;
-               pages = iommu_num_pages(s->offset, s->length);
+               pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE);
                while (pages--) {
                        iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
                        SET_LEAK(iommu_page);
@@ -451,7 +451,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 
                seg_size += s->length;
                need = nextneed;
-               pages += iommu_num_pages(s->offset, s->length);
+               pages += iommu_num_pages(s->offset, s->length, PAGE_SIZE);
                ps = s;
        }
        if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0)
index 8c3aca7cb343fb4d1cc93bf8e447b04b19839ff7..7ed9e070a6e930d97e2d55c8750a50f57a9baef1 100644 (file)
@@ -282,6 +282,8 @@ static void __cpuinit smp_callin(void)
        cpu_set(cpuid, cpu_callin_map);
 }
 
+static int __cpuinitdata unsafe_smp;
+
 /*
  * Activate a secondary processor.
  */
@@ -397,7 +399,7 @@ static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c)
                                goto valid_k7;
 
                /* If we get here, not a certified SMP capable AMD system. */
-               add_taint(TAINT_UNSAFE_SMP);
+               unsafe_smp = 1;
        }
 
 valid_k7:
@@ -414,12 +416,10 @@ static void __cpuinit smp_checks(void)
         * Don't taint if we are running SMP kernel on a single non-MP
         * approved Athlon
         */
-       if (tainted & TAINT_UNSAFE_SMP) {
-               if (num_online_cpus())
-                       printk(KERN_INFO "WARNING: This combination of AMD"
-                               "processors is not suitable for SMP.\n");
-               else
-                       tainted &= ~TAINT_UNSAFE_SMP;
+       if (unsafe_smp && num_online_cpus() > 1) {
+               printk(KERN_INFO "WARNING: This combination of AMD"
+                       "processors is not suitable for SMP.\n");
+               add_taint(TAINT_UNSAFE_SMP);
        }
 }
 
index 0d682fc6aeb333c382e6b9324105e2eb941bc545..19afbb644c7f7649420d1bbc5a7cba209e0b3f2b 100644 (file)
@@ -564,7 +564,7 @@ static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *
        hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32);
 
        pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n",
-                __FUNCTION__, tsc_khz, hv_clock->tsc_shift,
+                __func__, tsc_khz, hv_clock->tsc_shift,
                 hv_clock->tsc_to_system_mul);
 }
 
index 3f2b8962cbd0f71223ed8dfed8f90b893a966349..31e8730fa2463214f36c2f6b3df9d0f75f6be346 100644 (file)
@@ -640,24 +640,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
        }
 
 
-#ifdef CONFIG_X86_32
-       /* It's safe to allow irq's after cr2 has been saved and the vmalloc
-          fault has been handled. */
-       if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
-               local_irq_enable();
-
        /*
-        * If we're in an interrupt, have no user context or are running in an
-        * atomic region then we must not take the fault.
+        * It's safe to allow irq's after cr2 has been saved and the
+        * vmalloc fault has been handled.
+        *
+        * User-mode registers count as a user access even for any
+        * potential system fault or CPU buglet.
         */
-       if (in_atomic() || !mm)
-               goto bad_area_nosemaphore;
-#else /* CONFIG_X86_64 */
-       if (likely(regs->flags & X86_EFLAGS_IF))
+       if (user_mode_vm(regs)) {
+               local_irq_enable();
+               error_code |= PF_USER;
+       } else if (regs->flags & X86_EFLAGS_IF)
                local_irq_enable();
 
+#ifdef CONFIG_X86_64
        if (unlikely(error_code & PF_RSVD))
                pgtable_bad(address, regs, error_code);
+#endif
 
        /*
         * If we're in an interrupt, have no user context or are running in an
@@ -666,15 +665,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
        if (unlikely(in_atomic() || !mm))
                goto bad_area_nosemaphore;
 
-       /*
-        * User-mode registers count as a user access even for any
-        * potential system fault or CPU buglet.
-        */
-       if (user_mode_vm(regs))
-               error_code |= PF_USER;
 again:
-#endif
-       /* When running in the kernel we expect faults to occur only to
+       /*
+        * When running in the kernel we expect faults to occur only to
         * addresses in user space.  All other faults represent errors in the
         * kernel and should generate an OOPS.  Unfortunately, in the case of an
         * erroneous fault occurring in a code path which already holds mmap_sem
@@ -737,9 +730,6 @@ good_area:
                        goto bad_area;
        }
 
-#ifdef CONFIG_X86_32
-survive:
-#endif
        /*
         * If for any reason at all we couldn't handle the fault,
         * make sure we exit gracefully rather than endlessly redo
@@ -874,12 +864,11 @@ out_of_memory:
        up_read(&mm->mmap_sem);
        if (is_global_init(tsk)) {
                yield();
-#ifdef CONFIG_X86_32
-               down_read(&mm->mmap_sem);
-               goto survive;
-#else
+               /*
+                * Re-lookup the vma - in theory the vma tree might
+                * have changed:
+                */
                goto again;
-#endif
        }
 
        printk("VM: killing process %s\n", tsk->comm);
index 56cb343c76d8d4c507e80a7a08743b695d863756..034112bfe1f32a3876449533530edc0ed875e677 100644 (file)
@@ -1024,8 +1024,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
        bcd->release = release;
        kref_init(&bcd->ref);
        dev = MKDEV(bsg_major, bcd->minor);
-       class_dev = device_create_drvdata(bsg_class, parent, dev, NULL,
-                                         "%s", devname);
+       class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname);
        if (IS_ERR(class_dev)) {
                ret = PTR_ERR(class_dev);
                goto put_dev;
index 408da30594c442564f311deea0dcb62d7f14bc8b..1f18ad9e4fe161a6bfa33b84fff06c5c72626228 100644 (file)
@@ -52,7 +52,7 @@ static int __devinit pata_of_platform_probe(struct of_device *ofdev,
 
        ret = of_irq_to_resource(dn, 0, &irq_res);
        if (ret == NO_IRQ)
-               irq_res.start = irq_res.end = -1;
+               irq_res.start = irq_res.end = 0;
        else
                irq_res.flags = 0;
 
index 6318f6b573608f345129234abf85c2629f6df4a1..d8e8c49c0cbd195ec1b16d39f5b9d01a556f0fea 100644 (file)
@@ -54,7 +54,7 @@ config FIRMWARE_IN_KERNEL
          such firmware, and do not wish to use an initrd.
 
          This single option controls the inclusion of firmware for
-         every driver which usees request_firmare() and ships its
+         every driver which uses request_firmare() and ships its
          firmware in the kernel source tree, to avoid a proliferation
          of 'Include firmware for xxx device' options.
 
index ef522ae5548092f83ddabcbf36d7a54ad56f7282..5aee1c0169eafed102c699281b5bb4875fefd20c 100644 (file)
@@ -333,9 +333,7 @@ static int match_name(struct device *dev, void *data)
 {
        const char *name = data;
 
-       if (strcmp(name, dev->bus_id) == 0)
-               return 1;
-       return 0;
+       return sysfs_streq(name, dev->bus_id);
 }
 
 /**
@@ -982,6 +980,56 @@ struct klist *bus_get_device_klist(struct bus_type *bus)
 }
 EXPORT_SYMBOL_GPL(bus_get_device_klist);
 
+/*
+ * Yes, this forcably breaks the klist abstraction temporarily.  It
+ * just wants to sort the klist, not change reference counts and
+ * take/drop locks rapidly in the process.  It does all this while
+ * holding the lock for the list, so objects can't otherwise be
+ * added/removed while we're swizzling.
+ */
+static void device_insertion_sort_klist(struct device *a, struct list_head *list,
+                                       int (*compare)(const struct device *a,
+                                                       const struct device *b))
+{
+       struct list_head *pos;
+       struct klist_node *n;
+       struct device *b;
+
+       list_for_each(pos, list) {
+               n = container_of(pos, struct klist_node, n_node);
+               b = container_of(n, struct device, knode_bus);
+               if (compare(a, b) <= 0) {
+                       list_move_tail(&a->knode_bus.n_node,
+                                      &b->knode_bus.n_node);
+                       return;
+               }
+       }
+       list_move_tail(&a->knode_bus.n_node, list);
+}
+
+void bus_sort_breadthfirst(struct bus_type *bus,
+                          int (*compare)(const struct device *a,
+                                         const struct device *b))
+{
+       LIST_HEAD(sorted_devices);
+       struct list_head *pos, *tmp;
+       struct klist_node *n;
+       struct device *dev;
+       struct klist *device_klist;
+
+       device_klist = bus_get_device_klist(bus);
+
+       spin_lock(&device_klist->k_lock);
+       list_for_each_safe(pos, tmp, &device_klist->k_list) {
+               n = container_of(pos, struct klist_node, n_node);
+               dev = container_of(n, struct device, knode_bus);
+               device_insertion_sort_klist(dev, &sorted_devices, compare);
+       }
+       list_splice(&sorted_devices, &device_klist->k_list);
+       spin_unlock(&device_klist->k_lock);
+}
+EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
+
 int __init buses_init(void)
 {
        bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
index b98cb1416a2d7a8a74dd5f64e4d1f1abcc35fbf2..8c2cc2648f5a5c0ec330df4991f75b6be07131ae 100644 (file)
@@ -523,11 +523,16 @@ static void klist_children_put(struct klist_node *n)
  * device_initialize - init device structure.
  * @dev: device.
  *
- * This prepares the device for use by other layers,
- * including adding it to the device hierarchy.
+ * This prepares the device for use by other layers by initializing
+ * its fields.
  * It is the first half of device_register(), if called by
- * that, though it can also be called separately, so one
- * may use @dev's fields (e.g. the refcount).
+ * that function, though it can also be called separately, so one
+ * may use @dev's fields. In particular, get_device()/put_device()
+ * may be used for reference counting of @dev after calling this
+ * function.
+ *
+ * NOTE: Use put_device() to give up your reference instead of freeing
+ * @dev directly once you have called this function.
  */
 void device_initialize(struct device *dev)
 {
@@ -835,9 +840,13 @@ static void device_remove_sys_dev_entry(struct device *dev)
  * This is part 2 of device_register(), though may be called
  * separately _iff_ device_initialize() has been called separately.
  *
- * This adds it to the kobject hierarchy via kobject_add(), adds it
+ * This adds @dev to the kobject hierarchy via kobject_add(), adds it
  * to the global and sibling lists for the device, then
  * adds it to the other relevant subsystems of the driver model.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up your
+ * reference instead.
  */
 int device_add(struct device *dev)
 {
@@ -965,6 +974,10 @@ done:
  * I.e. you should only call the two helpers separately if
  * have a clearly defined need to use and refcount the device
  * before it is added to the hierarchy.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up the
+ * reference initialized in this function instead.
  */
 int device_register(struct device *dev)
 {
@@ -1243,7 +1256,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
        return dev;
 
 error:
-       kfree(dev);
+       put_device(dev);
        return ERR_PTR(retval);
 }
 EXPORT_SYMBOL_GPL(device_create_vargs);
@@ -1314,6 +1327,11 @@ EXPORT_SYMBOL_GPL(device_destroy);
  * device_rename - renames a device
  * @dev: the pointer to the struct device to be renamed
  * @new_name: the new name of the device
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of device_rename
+ * on the same device to ensure that new_name is valid and
+ * won't conflict with other devices.
  */
 int device_rename(struct device *dev, char *new_name)
 {
index 3ac443b2ac08579b978b7f49de2a2b73034a88cf..20febc00a5258e253aeb9a309a9447660df40a38 100644 (file)
@@ -257,6 +257,9 @@ static int __driver_attach(struct device *dev, void *data)
         * is an error.
         */
 
+       if (drv->bus->match && !drv->bus->match(dev, drv))
+               return 0;
+
        if (dev->parent)        /* Needed for USB */
                down(&dev->parent->sem);
        down(&dev->sem);
index c9c92b00fd555768730b731695bdbac1deeab1e9..b7e571031ecd144e12b7b8c361a9e6fb6ffd4961 100644 (file)
@@ -164,8 +164,7 @@ static ssize_t firmware_loading_store(struct device *dev,
                }
                /* fallthrough */
        default:
-               printk(KERN_ERR "%s: unexpected value (%d)\n", __func__,
-                      loading);
+               dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
                /* fallthrough */
        case -1:
                fw_load_abort(fw_priv);
@@ -309,7 +308,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
        *dev_p = NULL;
 
        if (!fw_priv || !f_dev) {
-               printk(KERN_ERR "%s: kmalloc failed\n", __func__);
+               dev_err(device, "%s: kmalloc failed\n", __func__);
                retval = -ENOMEM;
                goto error_kfree;
        }
@@ -329,8 +328,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
        f_dev->uevent_suppress = 1;
        retval = device_register(f_dev);
        if (retval) {
-               printk(KERN_ERR "%s: device_register failed\n",
-                      __func__);
+               dev_err(device, "%s: device_register failed\n", __func__);
                goto error_kfree;
        }
        *dev_p = f_dev;
@@ -363,15 +361,13 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
        fw_priv->fw = fw;
        retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
        if (retval) {
-               printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
-                      __func__);
+               dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
                goto error_unreg;
        }
 
        retval = device_create_file(f_dev, &dev_attr_loading);
        if (retval) {
-               printk(KERN_ERR "%s: device_create_file failed\n",
-                      __func__);
+               dev_err(device, "%s: device_create_file failed\n", __func__);
                goto error_unreg;
        }
 
@@ -401,8 +397,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 
        *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
        if (!firmware) {
-               printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
-                      __func__);
+               dev_err(device, "%s: kmalloc(struct firmware) failed\n",
+                       __func__);
                retval = -ENOMEM;
                goto out;
        }
@@ -411,15 +407,15 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
             builtin++) {
                if (strcmp(name, builtin->name))
                        continue;
-               printk(KERN_INFO "firmware: using built-in firmware %s\n",
-                      name);
+               dev_info(device, "firmware: using built-in firmware %s\n",
+                        name);
                firmware->size = builtin->size;
                firmware->data = builtin->data;
                return 0;
        }
 
        if (uevent)
-               printk(KERN_INFO "firmware: requesting %s\n", name);
+               dev_info(device, "firmware: requesting %s\n", name);
 
        retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
        if (retval)
index 3f940393d6c7904cdd68a5db804a3c0365ac696a..dfcbfe504867e9db43ea944c55cda9eae9328556 100644 (file)
@@ -42,10 +42,8 @@ struct resource *platform_get_resource(struct platform_device *dev,
        for (i = 0; i < dev->num_resources; i++) {
                struct resource *r = &dev->resource[i];
 
-               if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
-                                IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
-                       if (num-- == 0)
-                               return r;
+               if (type == resource_type(r) && num-- == 0)
+                       return r;
        }
        return NULL;
 }
@@ -78,10 +76,8 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
        for (i = 0; i < dev->num_resources; i++) {
                struct resource *r = &dev->resource[i];
 
-               if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
-                                IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
-                       if (!strcmp(r->name, name))
-                               return r;
+               if (type == resource_type(r) && !strcmp(r->name, name))
+                       return r;
        }
        return NULL;
 }
@@ -259,9 +255,9 @@ int platform_device_add(struct platform_device *pdev)
 
                p = r->parent;
                if (!p) {
-                       if (r->flags & IORESOURCE_MEM)
+                       if (resource_type(r) == IORESOURCE_MEM)
                                p = &iomem_resource;
-                       else if (r->flags & IORESOURCE_IO)
+                       else if (resource_type(r) == IORESOURCE_IO)
                                p = &ioport_resource;
                }
 
@@ -282,9 +278,14 @@ int platform_device_add(struct platform_device *pdev)
                return ret;
 
  failed:
-       while (--i >= 0)
-               if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))
-                       release_resource(&pdev->resource[i]);
+       while (--i >= 0) {
+               struct resource *r = &pdev->resource[i];
+               unsigned long type = resource_type(r);
+
+               if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
+                       release_resource(r);
+       }
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(platform_device_add);
@@ -306,7 +307,9 @@ void platform_device_del(struct platform_device *pdev)
 
                for (i = 0; i < pdev->num_resources; i++) {
                        struct resource *r = &pdev->resource[i];
-                       if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO))
+                       unsigned long type = resource_type(r);
+
+                       if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
                                release_resource(r);
                }
        }
@@ -391,6 +394,53 @@ error:
 }
 EXPORT_SYMBOL_GPL(platform_device_register_simple);
 
+/**
+ * platform_device_register_data
+ * @parent: parent device for the device we're adding
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * This function creates a simple platform device that requires minimal
+ * resource and memory management. Canned release function freeing memory
+ * allocated for the device allows drivers using such devices to be
+ * unloaded without waiting for the last reference to the device to be
+ * dropped.
+ */
+struct platform_device *platform_device_register_data(
+               struct device *parent,
+               const char *name, int id,
+               const void *data, size_t size)
+{
+       struct platform_device *pdev;
+       int retval;
+
+       pdev = platform_device_alloc(name, id);
+       if (!pdev) {
+               retval = -ENOMEM;
+               goto error;
+       }
+
+       pdev->dev.parent = parent;
+
+       if (size) {
+               retval = platform_device_add_data(pdev, data, size);
+               if (retval)
+                       goto error;
+       }
+
+       retval = platform_device_add(pdev);
+       if (retval)
+               goto error;
+
+       return pdev;
+
+error:
+       platform_device_put(pdev);
+       return ERR_PTR(retval);
+}
+
 static int platform_drv_probe(struct device *_dev)
 {
        struct platform_driver *drv = to_platform_driver(_dev->driver);
@@ -862,7 +912,7 @@ static int platform_pm_restore_noirq(struct device *dev)
 
 #endif /* !CONFIG_HIBERNATION */
 
-struct pm_ext_ops platform_pm_ops = {
+static struct pm_ext_ops platform_pm_ops = {
        .base = {
                .prepare = platform_pm_prepare,
                .complete = platform_pm_complete,
index 273a944d4040e861afa6a1ea6c601264eec6c4a7..692c20ba51444acaafe4ca2e1c63237afa3e42bf 100644 (file)
@@ -83,7 +83,7 @@ void device_pm_add(struct device *dev)
                 * transition is in progress in order to avoid leaving them
                 * unhandled down the road
                 */
-               WARN_ON(true);
+               dev_WARN(dev, "Parentless device registered during a PM transaction\n");
        }
 
        list_add_tail(&dev->power.entry, &dpm_list);
@@ -778,10 +778,7 @@ EXPORT_SYMBOL_GPL(device_suspend);
 
 void __suspend_report_result(const char *function, void *fn, int ret)
 {
-       if (ret) {
-               printk(KERN_ERR "%s(): ", function);
-               print_fn_descriptor_symbol("%s returns ", fn);
-               printk("%d\n", ret);
-       }
+       if (ret)
+               printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
 }
 EXPORT_SYMBOL_GPL(__suspend_report_result);
index 1f56d2c5b7fc67acb83899494c9376297a030f6c..200efc4d2c1e756cd9a7182709bbfb2328a57140 100644 (file)
@@ -284,9 +284,9 @@ aoechr_init(void)
                return PTR_ERR(aoe_class);
        }
        for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-               device_create_drvdata(aoe_class, NULL,
-                                     MKDEV(AOE_MAJOR, chardevs[i].minor),
-                                     NULL, chardevs[i].name);
+               device_create(aoe_class, NULL,
+                             MKDEV(AOE_MAJOR, chardevs[i].minor), NULL,
+                             chardevs[i].name);
 
        return 0;
 }
index cf64ddf5d83924a1c6445a207ee7d21825483436..2cea27aba9a06c385d62efc49749753da0ae26ce 100644 (file)
@@ -4172,7 +4172,7 @@ static int __init floppy_init(void)
        int i, unit, drive;
        int err, dr;
 
-#if defined(CONFIG_PPC_MERGE)
+#if defined(CONFIG_PPC)
        if (check_legacy_ioport(FDC1))
                return -ENODEV;
 #endif
index d731ca42f8024f48a12214b064ed5ff3d13b8543..9dfa27163001e9d31de36f5196be7db0f2334a2d 100644 (file)
@@ -686,9 +686,8 @@ static int __init pg_init(void)
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
                if (dev->present)
-                       device_create_drvdata(pg_class, NULL,
-                                             MKDEV(major, unit), NULL,
-                                             "pg%u", unit);
+                       device_create(pg_class, NULL, MKDEV(major, unit), NULL,
+                                     "pg%u", unit);
        }
        err = 0;
        goto out;
index 673b8b2fd337a1e22b442eba939aa4c90a407b86..5ae229656eaa0114e6d80508d1b3ad4417726fd8 100644 (file)
@@ -979,12 +979,10 @@ static int __init pt_init(void)
 
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
-                       device_create_drvdata(pt_class, NULL,
-                                             MKDEV(major, unit), NULL,
-                                             "pt%d", unit);
-                       device_create_drvdata(pt_class, NULL,
-                                             MKDEV(major, unit + 128), NULL,
-                                             "pt%dn", unit);
+                       device_create(pt_class, NULL, MKDEV(major, unit), NULL,
+                                     "pt%d", unit);
+                       device_create(pt_class, NULL, MKDEV(major, unit + 128),
+                                     NULL, "pt%dn", unit);
                }
        goto out;
 
index 0e077150568bbc78b5f44323019dd8a9bf643f87..195ca7c720f584efd0592e072096547423773357 100644 (file)
@@ -302,9 +302,8 @@ static struct kobj_type kobj_pkt_type_wqueue = {
 static void pkt_sysfs_dev_new(struct pktcdvd_device *pd)
 {
        if (class_pktcdvd) {
-               pd->dev = device_create_drvdata(class_pktcdvd, NULL,
-                                               pd->pkt_dev, NULL,
-                                               "%s", pd->name);
+               pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, NULL,
+                                       "%s", pd->name);
                if (IS_ERR(pd->dev))
                        pd->dev = NULL;
        }
index f1c8feb5510b1fd77922972df0ff08542d789f8e..1730d29e6044039d12a2da60ebfdf23ea225d0ef 100644 (file)
@@ -249,7 +249,6 @@ static int send_request(struct request *req)
        struct HvLpEvent *hev;
        struct scatterlist sg[VIOMAXBLOCKDMA];
        int sgindex;
-       int statindex;
        struct viodasd_device *d;
        unsigned long flags;
 
@@ -258,11 +257,9 @@ static int send_request(struct request *req)
        if (rq_data_dir(req) == READ) {
                direction = DMA_FROM_DEVICE;
                viocmd = viomajorsubtype_blockio | vioblockread;
-               statindex = 0;
        } else {
                direction = DMA_TO_DEVICE;
                viocmd = viomajorsubtype_blockio | vioblockwrite;
-               statindex = 1;
        }
 
         d = req->rq_disk->private_data;
index 700ff9679457efb2a6efe56604f4994ea11f76ab..122254155ae16019e4b56288b2fcdecf67509c6e 100644 (file)
@@ -1043,15 +1043,6 @@ config HPET
          open selects one of the timers supported by the HPET.  The timers are
          non-periodic and/or periodic.
 
-config HPET_RTC_IRQ
-       bool
-       default HPET_EMULATE_RTC
-       depends on RTC && HPET
-       help
-         If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It
-         is assumed the platform called hpet_alloc with the RTC IRQ values for
-         the HPET timers.
-
 config HPET_MMAP
        bool "Allow mmap of HPET"
        default y
index 603a986e96af6299bd6bc9b2e10bb54edc3aea2c..3f98254b911f01cfaae8711dbfda8cadaf451c77 100644 (file)
@@ -223,12 +223,14 @@ static int amd_irongate_configure(void)
 
        current_size = A_SIZE_LVL2(agp_bridge->current_size);
 
-       /* Get the memory mapped registers */
-       pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
-       temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-       amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
-       if (!amd_irongate_private.registers)
-               return -ENOMEM;
+       if (!amd_irongate_private.registers) {
+               /* Get the memory mapped registers */
+               pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
+               temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+               amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
+               if (!amd_irongate_private.registers)
+                       return -ENOMEM;
+       }
 
        /* Write out the address of the gatt table */
        writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE);
@@ -492,6 +494,26 @@ static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
        agp_put_bridge(bridge);
 }
 
+#ifdef CONFIG_PM
+
+static int agp_amdk7_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       pci_save_state(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+static int agp_amdk7_resume(struct pci_dev *pdev)
+{
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+
+       return amd_irongate_driver.configure();
+}
+
+#endif /* CONFIG_PM */
+
 /* must be the same order as name table above */
 static struct pci_device_id agp_amdk7_pci_table[] = {
        {
@@ -528,6 +550,10 @@ static struct pci_driver agp_amdk7_pci_driver = {
        .id_table       = agp_amdk7_pci_table,
        .probe          = agp_amdk7_probe,
        .remove         = agp_amdk7_remove,
+#ifdef CONFIG_PM
+       .suspend        = agp_amdk7_suspend,
+       .resume         = agp_amdk7_resume,
+#endif
 };
 
 static int __init agp_amdk7_init(void)
index 043e36628d6d7faf03c34e5f7a2f9956f5429694..1108665913e207da892459750377400db809c961 100644 (file)
@@ -54,8 +54,7 @@
                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
-                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
-                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
+                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
 
 #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
@@ -63,7 +62,8 @@
 
 #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB)
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
 
 extern int agp_memory_reserved;
 
@@ -214,8 +214,8 @@ static int intel_i810_configure(void)
        if (agp_bridge->driver->needs_scratch_page) {
                for (i = 0; i < current_size->num_entries; i++) {
                        writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
-                       readl(intel_private.registers+I810_PTE_BASE+(i*4));     /* PCI posting. */
                }
+               readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI posting. */
        }
        global_cache_flush();
        return 0;
@@ -525,8 +525,10 @@ static void intel_i830_init_gtt_entries(void)
                size += 4;
        } else if (IS_G4X) {
                /* On 4 series hardware, GTT stolen is separate from graphics
-                * stolen, ignore it in stolen gtt entries counting */
-               size = 0;
+                * stolen, ignore it in stolen gtt entries counting.  However,
+                * 4KB of the stolen memory doesn't get mapped to the GTT.
+                */
+               size = 4;
        } else {
                /* On previous hardware, the GTT size was just what was
                 * required to map the aperture.
@@ -773,8 +775,8 @@ static int intel_i830_configure(void)
        if (agp_bridge->driver->needs_scratch_page) {
                for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
                        writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
-                       readl(intel_private.registers+I810_PTE_BASE+(i*4));     /* PCI Posting. */
                }
+               readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */
        }
 
        global_cache_flush();
@@ -989,8 +991,8 @@ static int intel_i915_configure(void)
        if (agp_bridge->driver->needs_scratch_page) {
                for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
                        writel(agp_bridge->scratch_page, intel_private.gtt+i);
-                       readl(intel_private.gtt+i);     /* PCI Posting. */
                }
+               readl(intel_private.gtt+i-1);   /* PCI Posting. */
        }
 
        global_cache_flush();
index dc70d3771811a1d820bc020d73929ebfd491ad18..5bbed3d79db95f9d62ec32132817d645a961c7d2 100644 (file)
@@ -201,10 +201,15 @@ extern int agp_memory_reserved;
 static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
        int i, j;
+       int mask_type;
 
-       if ((type != 0) || (mem->type != 0))
+       mask_type = agp_generic_type_to_mask_type(mem->bridge, type);
+       if (mask_type != 0 || type != mem->type)
                return -EINVAL;
 
+       if (mem->page_count == 0)
+               return 0;
+
        if ((pg_start + mem->page_count) >
                (nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE))
                return -EINVAL;
@@ -220,10 +225,13 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type
        }
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(agp_bridge->driver->mask_memory(agp_bridge,
-                       mem->memory[i], mem->type),
+                       mem->memory[i], mask_type),
                        agp_bridge->gatt_table+nvidia_private.pg_offset+j);
-               readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j);       /* PCI Posting. */
        }
+
+       /* PCI Posting. */
+       readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j - 1);
+
        agp_bridge->driver->tlb_flush(mem);
        return 0;
 }
@@ -233,9 +241,15 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type
 {
        int i;
 
-       if ((type != 0) || (mem->type != 0))
+       int mask_type;
+
+       mask_type = agp_generic_type_to_mask_type(mem->bridge, type);
+       if (mask_type != 0 || type != mem->type)
                return -EINVAL;
 
+       if (mem->page_count == 0)
+               return 0;
+
        for (i = pg_start; i < (mem->page_count + pg_start); i++)
                writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i);
 
index b899d9182c7dec0b0b03e2857b680a30806cf12e..05674febb0c6bff218d2c76373402e7fcf0e1f58 100644 (file)
@@ -478,7 +478,7 @@ static int do_ac_read(int IndexCard, char __user *buf,
                struct st_ram_io *st_loc, struct mailbox *mailbox)
 {
        void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC;
-       unsigned char *to = (unsigned char *)&mailbox;
+       unsigned char *to = (unsigned char *)mailbox;
 #ifdef DEBUG
        int c;
 #endif
index b650b4e48e5042654c139ea0777befe7bbebab4a..456f54db73e2aa0fa395ede67cad3b2b80a40feb 100644 (file)
@@ -229,9 +229,8 @@ static int bsr_create_devs(struct device_node *bn)
                if (result)
                        goto out_err;
 
-               cur->bsr_device = device_create_drvdata(bsr_class, NULL,
-                                                       cur->bsr_dev,
-                                                       cur, cur->bsr_name);
+               cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev,
+                                               cur, cur->bsr_name);
                if (!cur->bsr_device) {
                        printk(KERN_ERR "device_create failed for %s\n",
                               cur->bsr_name);
index fb584938c9c3b2eb81bb954a8a8af41fa40fbf00..5329d482b582bd06fff9d4acf66b044683de05e5 100644 (file)
@@ -443,7 +443,6 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
 {
        unsigned char save_control;
        unsigned long flags;
-       unsigned long uip_watchdog = jiffies;
 
        /*
         * read RTC once any update in progress is done. The update
@@ -456,8 +455,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
         */
 
        if (ds1286_is_updating() != 0)
-               while (time_before(jiffies, uip_watchdog + 2*HZ/100))
-                       barrier();
+               msleep(20);
 
        /*
         * Only the values that we read from the RTC are set. We leave
index ca7c72a486b2f1391d57b07621c19e28cb37d65d..85832ab924e662ffa3f1d4cf588c1b5fb7becab2 100644 (file)
@@ -508,8 +508,8 @@ static int __init dsp56k_init_driver(void)
                err = PTR_ERR(dsp56k_class);
                goto out_chrdev;
        }
-       device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0),
-                             NULL, "dsp56k");
+       device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL,
+                     "dsp56k");
 
        printk(banner);
        goto out;
index ec7aded0a2df9050389cba0d398d6959fdb58162..bf70450a49ccbc403c62917c53f0db73f7328f5d 100644 (file)
@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
        spin_lock_irqsave(&hp->lock, flags);
 
        if (--hp->count == 0) {
-               if (hp->ops->notifier_del)
-                       hp->ops->notifier_del(hp, hp->data);
-
                /* We are done with the tty pointer now. */
                hp->tty = NULL;
                spin_unlock_irqrestore(&hp->lock, flags);
 
+               if (hp->ops->notifier_del)
+                       hp->ops->notifier_del(hp, hp->data);
+
                /*
                 * Chain calls chars_in_buffer() and returns immediately if
                 * there is no buffered data otherwise sleeps on a wait queue
@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct *tty)
        hp->n_outbuf = 0;
        hp->tty = NULL;
 
+       spin_unlock_irqrestore(&hp->lock, flags);
+
        if (hp->ops->notifier_del)
                        hp->ops->notifier_del(hp, hp->data);
 
-       spin_unlock_irqrestore(&hp->lock, flags);
-
        while(temp_open_count) {
                --temp_open_count;
                kref_put(&hp->kref, destroy_hvc_struct);
index 51738bdd834eccd732eb234b8cddd7cb1c83ed61..d4e7dca06e4fa2c6e7bf0d26781ac5627abb97cc 100644 (file)
@@ -118,18 +118,21 @@ static int __init omap_rng_probe(struct platform_device *pdev)
 
        mem = request_mem_region(res->start, res->end - res->start + 1,
                                 pdev->name);
-       if (mem == NULL)
-               return -EBUSY;
+       if (mem == NULL) {
+               ret = -EBUSY;
+               goto err_region;
+       }
 
        dev_set_drvdata(&pdev->dev, mem);
-       rng_base = (u32 __force __iomem *)io_p2v(res->start);
+       rng_base = ioremap(res->start, res->end - res->start + 1);
+       if (!rng_base) {
+               ret = -ENOMEM;
+               goto err_ioremap;
+       }
 
        ret = hwrng_register(&omap_rng_ops);
-       if (ret) {
-               release_resource(mem);
-               rng_base = NULL;
-               return ret;
-       }
+       if (ret)
+               goto err_register;
 
        dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
                omap_rng_read_reg(RNG_REV_REG));
@@ -138,6 +141,18 @@ static int __init omap_rng_probe(struct platform_device *pdev)
        rng_dev = pdev;
 
        return 0;
+
+err_register:
+       iounmap(rng_base);
+       rng_base = NULL;
+err_ioremap:
+       release_resource(mem);
+err_region:
+       if (cpu_is_omap24xx()) {
+               clk_disable(rng_ick);
+               clk_put(rng_ick);
+       }
+       return ret;
 }
 
 static int __exit omap_rng_remove(struct platform_device *pdev)
@@ -148,6 +163,8 @@ static int __exit omap_rng_remove(struct platform_device *pdev)
 
        omap_rng_write_reg(RNG_MASK_REG, 0x0);
 
+       iounmap(rng_base);
+
        if (cpu_is_omap24xx()) {
                clk_disable(rng_ick);
                clk_put(rng_ick);
index 6774572d3759e19e2c25fca4e623088cf426643a..70e0ebc30bd08d5b9e034b2b22c341475c761252 100644 (file)
@@ -745,12 +745,12 @@ static int __init ip2_loadmain(void)
 
                pB = i2BoardPtrTable[i];
                if (pB != NULL) {
-                       device_create_drvdata(ip2_class, NULL,
-                                             MKDEV(IP2_IPL_MAJOR, 4 * i),
-                                             NULL, "ipl%d", i);
-                       device_create_drvdata(ip2_class, NULL,
-                                             MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
-                                             NULL, "stat%d", i);
+                       device_create(ip2_class, NULL,
+                                     MKDEV(IP2_IPL_MAJOR, 4 * i),
+                                     NULL, "ipl%d", i);
+                       device_create(ip2_class, NULL,
+                                     MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+                                     NULL, "stat%d", i);
 
                        for (box = 0; box < ABS_MAX_BOXES; box++)
                                for (j = 0; j < ABS_BIGGEST_BOX; j++)
index 64e1c169e826814c922c6937f738424ba819891b..835a33c8d5f510c7ff0ae3e0360e6ef8ec7f2551 100644 (file)
@@ -871,7 +871,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
        entry->dev = dev;
 
        mutex_lock(&reg_list_mutex);
-       device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
+       device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
        list_add(&entry->link, &reg_list);
        mutex_unlock(&reg_list_mutex);
 }
index 8e8afb6141f99edc8f3a38bbcad1e1b9e802961f..3123bf57ad91365039b9b227dc8fb3182a944c06 100644 (file)
@@ -2695,7 +2695,7 @@ static __devinit void default_find_bmc(void)
        for (i = 0; ; i++) {
                if (!ipmi_defaults[i].port)
                        break;
-#ifdef CONFIG_PPC_MERGE
+#ifdef CONFIG_PPC
                if (check_legacy_ioport(ipmi_defaults[i].port))
                        continue;
 #endif
index 505d7a1f6b8cc39a37c0b9b3e0d04e06f796aba2..44e5d60f517ebd504c0161d516442c76a42f5e57 100644 (file)
@@ -4600,9 +4600,8 @@ static int __init istallion_module_init(void)
 
        istallion_class = class_create(THIS_MODULE, "staliomem");
        for (i = 0; i < 4; i++)
-               device_create_drvdata(istallion_class, NULL,
-                                     MKDEV(STL_SIOMEMMAJOR, i),
-                                     NULL, "staliomem%d", i);
+               device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+                             NULL, "staliomem%d", i);
 
        return 0;
 err_deinit:
index 7b3a212c86b1ab21d5e3d783716ded2787f3729d..de26a978fbdd140aec88179b99c14fae555c467c 100644 (file)
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
                return;
        }
 
-       if (keycode > NR_KEYS)
+       if (keycode >= NR_KEYS)
                if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
                        keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
                else
index 3f2719b9f77b5fca364477dfa7d096c66be759cb..e444c2dba160870658b8ac45910ba79b85d12419 100644 (file)
@@ -813,8 +813,8 @@ static int lp_register(int nr, struct parport *port)
        if (reset)
                lp_reset(nr);
 
-       device_create_drvdata(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
-                             "lp%d", nr);
+       device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
+                     "lp%d", nr);
 
        printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 
               (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
index 672b08e694d05cd041e8a3bbac17264f3ca2fb4e..6431f6921a67acde3c214f784904c4ebd0f62678 100644 (file)
@@ -992,9 +992,9 @@ static int __init chr_dev_init(void)
 
        mem_class = class_create(THIS_MODULE, "mem");
        for (i = 0; i < ARRAY_SIZE(devlist); i++)
-               device_create_drvdata(mem_class, NULL,
-                                     MKDEV(MEM_MAJOR, devlist[i].minor),
-                                     NULL, devlist[i].name);
+               device_create(mem_class, NULL,
+                             MKDEV(MEM_MAJOR, devlist[i].minor), NULL,
+                             devlist[i].name);
 
        return 0;
 }
index 999aa779c08a710601fabc93cacb6f52229c53ba..a5e0db9d7662d4a060ff167260753b193a64ee9f 100644 (file)
@@ -217,8 +217,8 @@ int misc_register(struct miscdevice * misc)
                misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
        dev = MKDEV(MISC_MAJOR, misc->minor);
 
-       misc->this_device = device_create_drvdata(misc_class, misc->parent,
-                                                 dev, NULL, "%s", misc->name);
+       misc->this_device = device_create(misc_class, misc->parent, dev, NULL,
+                                         "%s", misc->name);
        if (IS_ERR(misc->this_device)) {
                err = PTR_ERR(misc->this_device);
                goto out;
index 5df4003ad8736f0e544dbc685010f7d8da783be1..12d327a2c9ba72cadd471670f6300cca3e9a1ad0 100644 (file)
@@ -513,7 +513,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
                size_t len)
 {
        void __iomem *baseAddr = brd->basemem;
-       const u16 *uptr = ptr;
+       const __le16 *uptr = ptr;
        size_t wlen, len2, j;
        unsigned long key, loadbuf, loadlen, checksum, checksum_ok;
        unsigned int i, retry;
index 1c5bf99895edda84f0571ff91851b828aa988f79..dbb912574569ef49375866a5053e429bf6d38831 100644 (file)
@@ -1871,7 +1871,7 @@ static int cm4000_probe(struct pcmcia_device *link)
                return ret;
        }
 
-       device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
+       device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
 
        return 0;
 }
index 2d7c906435b7be8a6b60e9e4e19ec2a727578304..4f0723b07974615f5177134b49deb671580e8813 100644 (file)
@@ -637,8 +637,7 @@ static int reader_probe(struct pcmcia_device *link)
                return ret;
        }
 
-       device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL,
-                             "cmx%d", i);
+       device_create(cmx_class, NULL, MKDEV(major, i), NULL, "cmx%d", i);
 
        return 0;
 }
index bee39fdfba738de8a11429a1d2c57caa7b99cc26..c84c34fb123116d0b43b0ec491aacce84342f5bc 100644 (file)
@@ -760,9 +760,8 @@ static const struct file_operations pp_fops = {
 
 static void pp_attach(struct parport *port)
 {
-       device_create_drvdata(ppdev_class, port->dev,
-                             MKDEV(PP_MAJOR, port->number),
-                             NULL, "parport%d", port->number);
+       device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
+                     NULL, "parport%d", port->number);
 }
 
 static void pp_detach(struct parport *port)
index 6af435b89867a7bb99689871624989dd8de14e61..c8752eaad483eea52b4dbc8c8af87eaf931ad189 100644 (file)
@@ -1205,7 +1205,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
        return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos);
 }
 
-static int uuid_strategy(ctl_table *table, int __user *name, int nlen,
+static int uuid_strategy(ctl_table *table,
                         void __user *oldval, size_t __user *oldlenp,
                         void __user *newval, size_t newlen)
 {
index 47b8cf281d4a79766c0717dec1ea4380d2bf9717..e139372d0e6913f1d09a385a8d60617b3e25e089 100644 (file)
@@ -131,8 +131,8 @@ raw_ioctl(struct inode *inode, struct file *filp,
 static void bind_device(struct raw_config_request *rq)
 {
        device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
-       device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
-                             NULL, "raw%d", rq->raw_minor);
+       device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL,
+                     "raw%d", rq->raw_minor);
 }
 
 /*
@@ -283,8 +283,7 @@ static int __init raw_init(void)
                ret = PTR_ERR(raw_class);
                goto error_region;
        }
-       device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL,
-                             "rawctl");
+       device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 
        return 0;
 
index b47710c178855399395b40b41edbc140981df683..17683de95717e2a2b5eb763fa345ce418fed6181 100644 (file)
@@ -96,7 +96,7 @@ static unsigned long rtc_port;
 static int rtc_irq;
 #endif
 
-#ifdef CONFIG_HPET_RTC_IRQ
+#ifdef CONFIG_HPET_EMULATE_RTC
 #undef RTC_IRQ
 #endif
 
index 3ce60df14c0a623f5aff950148f034938988a5f9..32b74de18f5face7e590ac25fc955aef373c6247 100644 (file)
@@ -444,8 +444,8 @@ scdrv_init(void)
                                continue;
                        }
 
-                       device_create_drvdata(snsc_class, NULL, dev, NULL,
-                                             "%s", devname);
+                       device_create(snsc_class, NULL, dev, NULL,
+                                     "%s", devname);
 
                        ia64_sn_irtr_intr_enable(scd->scd_nasid,
                                                 0 /*ignored */ ,
index 8b8f07a7f50529f1e67eaac40f0a4c43f4f1b0ed..963b03fb29e5583aa45e83f056c6cf1ff412ba43 100644 (file)
@@ -4743,8 +4743,8 @@ static int __init stallion_module_init(void)
        if (IS_ERR(stallion_class))
                printk("STALLION: failed to create class\n");
        for (i = 0; i < 4; i++)
-               device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
-                                     NULL, "staliomem%d", i);
+               device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+                             NULL, "staliomem%d", i);
 
        return 0;
 err_unrtty:
index 8fdfe9c871e3af99f5a632d2f893bbd0508455ab..dce4cc0e695338210391a11311507ef1b8d49f76 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/reboot.h>
 #include <linux/sysrq.h>
 #include <linux/kbd_kern.h>
+#include <linux/proc_fs.h>
 #include <linux/quotaops.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -326,6 +327,7 @@ static struct sysrq_key_op sysrq_moom_op = {
        .handler        = sysrq_handle_moom,
        .help_msg       = "Full",
        .action_msg     = "Manual OOM execution",
+       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
 };
 
 static void sysrq_handle_kill(int key, struct tty_struct *tty)
@@ -533,3 +535,32 @@ 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, NULL, 0);
+       }
+       return count;
+}
+
+static const struct file_operations proc_sysrq_trigger_operations = {
+       .write          = write_sysrq_trigger,
+};
+
+static int __init sysrq_init(void)
+{
+       proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
+       return 0;
+}
+module_init(sysrq_init);
+#endif
index 1fee7034a386f4aa27cf1c5928e8e195f832c0fb..e70d13defde4bcc30724187ff6443f553730eeb7 100644 (file)
@@ -525,19 +525,19 @@ void tpm_get_timeouts(struct tpm_chip *chip)
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
        if (timeout)
-               chip->vendor.timeout_a = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_a = usecs_to_jiffies(timeout);
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
        if (timeout)
-               chip->vendor.timeout_b = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_b = usecs_to_jiffies(timeout);
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
        if (timeout)
-               chip->vendor.timeout_c = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_c = usecs_to_jiffies(timeout);
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
        if (timeout)
-               chip->vendor.timeout_d = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_d = usecs_to_jiffies(timeout);
 
 duration:
        memcpy(data, tpm_cap, sizeof(tpm_cap));
@@ -554,15 +554,22 @@ duration:
                return;
 
        chip->vendor.duration[TPM_SHORT] =
-           msecs_to_jiffies(be32_to_cpu
+           usecs_to_jiffies(be32_to_cpu
                             (*((__be32 *) (data +
                                            TPM_GET_CAP_RET_UINT32_1_IDX))));
+       /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
+        * value wrong and apparently reports msecs rather than usecs. So we
+        * fix up the resulting too-small TPM_SHORT value to make things work.
+        */
+       if (chip->vendor.duration[TPM_SHORT] < (HZ/100))
+               chip->vendor.duration[TPM_SHORT] = HZ;
+
        chip->vendor.duration[TPM_MEDIUM] =
-           msecs_to_jiffies(be32_to_cpu
+           usecs_to_jiffies(be32_to_cpu
                             (*((__be32 *) (data +
                                            TPM_GET_CAP_RET_UINT32_2_IDX))));
        chip->vendor.duration[TPM_LONG] =
-           msecs_to_jiffies(be32_to_cpu
+           usecs_to_jiffies(be32_to_cpu
                             (*((__be32 *) (data +
                                            TPM_GET_CAP_RET_UINT32_3_IDX))));
 }
@@ -1180,11 +1187,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
 
-       if (chip == NULL || devname == NULL) {
-               kfree(chip);
-               kfree(devname);
-               return NULL;
-       }
+       if (chip == NULL || devname == NULL)
+               goto out_free;
 
        mutex_init(&chip->buffer_mutex);
        mutex_init(&chip->tpm_mutex);
@@ -1201,8 +1205,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
 
        if (chip->dev_num >= TPM_NUM_DEVICES) {
                dev_err(dev, "No available tpm device numbers\n");
-               kfree(chip);
-               return NULL;
+               goto out_free;
        } else if (chip->dev_num == 0)
                chip->vendor.miscdev.minor = TPM_MINOR;
        else
@@ -1243,6 +1246,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
        spin_unlock(&driver_lock);
 
        return chip;
+
+out_free:
+       kfree(chip);
+       kfree(devname);
+       return NULL;
 }
 EXPORT_SYMBOL_GPL(tpm_register_hardware);
 
index 7053d6333692d7bd8fcd112a4dfc8bac783ccbc0..59f472143f087d9486d62bd9f3842c2a9aee7eb6 100644 (file)
@@ -2850,7 +2850,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
        else
                tty_line_name(driver, index, name);
 
-       return device_create_drvdata(tty_class, device, dev, NULL, name);
+       return device_create(tty_class, device, dev, NULL, name);
 }
 EXPORT_SYMBOL(tty_register_device);
 
@@ -3032,11 +3032,12 @@ EXPORT_SYMBOL(tty_devnum);
 
 void proc_clear_tty(struct task_struct *p)
 {
+       unsigned long flags;
        struct tty_struct *tty;
-       spin_lock_irq(&p->sighand->siglock);
+       spin_lock_irqsave(&p->sighand->siglock, flags);
        tty = p->signal->tty;
        p->signal->tty = NULL;
-       spin_unlock_irq(&p->sighand->siglock);
+       spin_unlock_irqrestore(&p->sighand->siglock, flags);
        tty_kref_put(tty);
 }
 
index c2ae52dd53d1a6447affa697afaa53c9f9f9f7f7..4f3b3f95fc42b4bb7bcf03a561aa5f69c48a393d 100644 (file)
@@ -481,10 +481,10 @@ static struct class *vc_class;
 
 void vcs_make_sysfs(struct tty_struct *tty)
 {
-       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
-                             NULL, "vcs%u", tty->index + 1);
-       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
-                             NULL, "vcsa%u", tty->index + 1);
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
+                     "vcs%u", tty->index + 1);
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
+                     "vcsa%u", tty->index + 1);
 }
 
 void vcs_remove_sysfs(struct tty_struct *tty)
@@ -499,7 +499,7 @@ int __init vcs_init(void)
                panic("unable to get major %d for vcs device", VCS_MAJOR);
        vc_class = class_create(THIS_MODULE, "vc");
 
-       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
-       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
        return 0;
 }
index 7a70a40ad639855b4f3880386ef7b34f47d71f46..ffc9254f7e029d26c7cd0d0d38f75d7f32570e2c 100644 (file)
@@ -886,10 +886,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        state[i].cur_part = 0;
        for (j = 0; j < MAX_PARTITIONS; ++j)
                state[i].part_stat_rwi[j] = VIOT_IDLE;
-       device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
-                             NULL, "iseries!vt%d", i);
-       device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
-                             NULL, "iseries!nvt%d", i);
+       device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
+                     "iseries!vt%d", i);
+       device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL,
+                     "iseries!nvt%d", i);
        printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
                        "resource %10.10s type %4.4s, model %3.3s\n",
                        i, viotape_unitinfo[i].rsrcname,
index a0f7ffb6808716679ed1bc6d4cefb088ad0ba972..d8f83e26e4a4de09210646ea5733d719c42649b4 100644 (file)
@@ -59,7 +59,7 @@
  * 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 <andrewm@uow.edu.au>
+ * deletion SMP-safe.  17Jun00, Andrew Morton
  *
  * Removed console_lock, enabled interrupts across all console operations
  * 13 March 2001, Andrew Morton
index 278c9857bcf548c14de1c8b7fed133530c6e82f4..ed132fe55d3d35aad97339593d5a131fc601b8ba 100644 (file)
@@ -657,8 +657,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
                goto failed3;
        }
 
-       device_create_drvdata(icap_class, dev, devt, NULL,
-                             "%s%d", DRIVER_NAME, id);
+       device_create(icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id);
        return 0;               /* success */
 
  failed3:
index 7af4b403bd2d12a6f3219f8f8d6615f5de69def1..bb538b9690e08186ae6c7d73240901b95b6b9ee3 100644 (file)
@@ -15,9 +15,8 @@ int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
        struct device *cd;
        static int req_count;
 
-       cd = device_create_drvdata(dca_class, dca->cd,
-                                  MKDEV(0, slot + 1), NULL,
-                                  "requester%d", req_count++);
+       cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL,
+                          "requester%d", req_count++);
        if (IS_ERR(cd))
                return PTR_ERR(cd);
        return 0;
@@ -48,8 +47,7 @@ idr_try_again:
                return err;
        }
 
-       cd = device_create_drvdata(dca_class, dev, MKDEV(0, 0), NULL,
-                                  "dca%d", dca->id);
+       cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
        if (IS_ERR(cd)) {
                spin_lock(&dca_idr_lock);
                idr_remove(&dca_idr, dca->id);
index 4a16b5b61cfbdc702530e735af2bbb7a0eac1d2b..f0d9b415db50741bc18f73614be3e7730623b411 100644 (file)
 #define                        FERR_NF_UNCORRECTABLE   (FERR_NF_M12ERR | \
                                                        FERR_NF_M11ERR | \
                                                        FERR_NF_M10ERR | \
+                                                       FERR_NF_M9ERR | \
                                                        FERR_NF_M8ERR | \
                                                        FERR_NF_M7ERR | \
                                                        FERR_NF_M6ERR | \
@@ -301,6 +302,9 @@ static char *numcol_toString[] = {
 };
 #endif
 
+/* enables the report of miscellaneous messages as CE errors - default off */
+static int misc_messages;
+
 /* Enumeration of supported devices */
 enum i5000_chips {
        I5000P = 0,
@@ -466,7 +470,8 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
                                        struct i5000_error_info *info,
                                        int handle_errors)
 {
-       char msg[EDAC_MC_LABEL_LEN + 1 + 90];
+       char msg[EDAC_MC_LABEL_LEN + 1 + 160];
+       char *specific = NULL;
        u32 allErrors;
        int branch;
        int channel;
@@ -480,11 +485,6 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
        if (!allErrors)
                return;         /* if no error, return now */
 
-       /* ONLY ONE of the possible error bits will be set, as per the docs */
-       i5000_mc_printk(mci, KERN_ERR,
-                       "FATAL ERRORS Found!!! 1st FATAL Err Reg= 0x%x\n",
-                       allErrors);
-
        branch = EXTRACT_FBDCHAN_INDX(info->ferr_fat_fbd);
        channel = branch;
 
@@ -501,28 +501,42 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
                rdwr ? "Write" : "Read", ras, cas);
 
        /* Only 1 bit will be on */
-       if (allErrors & FERR_FAT_M1ERR) {
-               i5000_mc_printk(mci, KERN_ERR,
-                               "Alert on non-redundant retry or fast "
-                               "reset timeout\n");
-
-       } else if (allErrors & FERR_FAT_M2ERR) {
-               i5000_mc_printk(mci, KERN_ERR,
-                               "Northbound CRC error on non-redundant "
-                               "retry\n");
-
-       } else if (allErrors & FERR_FAT_M3ERR) {
-               i5000_mc_printk(mci, KERN_ERR,
-                               ">Tmid Thermal event with intelligent "
-                               "throttling disabled\n");
+       switch (allErrors) {
+       case FERR_FAT_M1ERR:
+               specific = "Alert on non-redundant retry or fast "
+                               "reset timeout";
+               break;
+       case FERR_FAT_M2ERR:
+               specific = "Northbound CRC error on non-redundant "
+                               "retry";
+               break;
+       case FERR_FAT_M3ERR:
+               {
+               static int done;
+
+               /*
+                * This error is generated to inform that the intelligent
+                * throttling is disabled and the temperature passed the
+                * specified middle point. Since this is something the BIOS
+                * should take care of, we'll warn only once to avoid
+                * worthlessly flooding the log.
+                */
+               if (done)
+                       return;
+               done++;
+
+               specific = ">Tmid Thermal event with intelligent "
+                          "throttling disabled";
+               }
+               break;
        }
 
        /* Form out message */
        snprintf(msg, sizeof(msg),
                 "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d CAS=%d "
-                "FATAL Err=0x%x)",
+                "FATAL Err=0x%x (%s))",
                 branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas,
-                allErrors);
+                allErrors, specific);
 
        /* Call the helper to output message */
        edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
@@ -539,7 +553,8 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
                                        struct i5000_error_info *info,
                                        int handle_errors)
 {
-       char msg[EDAC_MC_LABEL_LEN + 1 + 90];
+       char msg[EDAC_MC_LABEL_LEN + 1 + 170];
+       char *specific = NULL;
        u32 allErrors;
        u32 ue_errors;
        u32 ce_errors;
@@ -557,10 +572,6 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
                return;         /* if no error, return now */
 
        /* ONLY ONE of the possible error bits will be set, as per the docs */
-       i5000_mc_printk(mci, KERN_WARNING,
-                       "NON-FATAL ERRORS Found!!! 1st NON-FATAL Err "
-                       "Reg= 0x%x\n", allErrors);
-
        ue_errors = allErrors & FERR_NF_UNCORRECTABLE;
        if (ue_errors) {
                debugf0("\tUncorrected bits= 0x%x\n", ue_errors);
@@ -579,12 +590,47 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
                        rank, channel, channel + 1, branch >> 1, bank,
                        rdwr ? "Write" : "Read", ras, cas);
 
+               switch (ue_errors) {
+               case FERR_NF_M12ERR:
+                       specific = "Non-Aliased Uncorrectable Patrol Data ECC";
+                       break;
+               case FERR_NF_M11ERR:
+                       specific = "Non-Aliased Uncorrectable Spare-Copy "
+                                       "Data ECC";
+                       break;
+               case FERR_NF_M10ERR:
+                       specific = "Non-Aliased Uncorrectable Mirrored Demand "
+                                       "Data ECC";
+                       break;
+               case FERR_NF_M9ERR:
+                       specific = "Non-Aliased Uncorrectable Non-Mirrored "
+                                       "Demand Data ECC";
+                       break;
+               case FERR_NF_M8ERR:
+                       specific = "Aliased Uncorrectable Patrol Data ECC";
+                       break;
+               case FERR_NF_M7ERR:
+                       specific = "Aliased Uncorrectable Spare-Copy Data ECC";
+                       break;
+               case FERR_NF_M6ERR:
+                       specific = "Aliased Uncorrectable Mirrored Demand "
+                                       "Data ECC";
+                       break;
+               case FERR_NF_M5ERR:
+                       specific = "Aliased Uncorrectable Non-Mirrored Demand "
+                                       "Data ECC";
+                       break;
+               case FERR_NF_M4ERR:
+                       specific = "Uncorrectable Data ECC on Replay";
+                       break;
+               }
+
                /* Form out message */
                snprintf(msg, sizeof(msg),
                         "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d "
-                        "CAS=%d, UE Err=0x%x)",
+                        "CAS=%d, UE Err=0x%x (%s))",
                         branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas,
-                        ue_errors);
+                        ue_errors, specific);
 
                /* Call the helper to output message */
                edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
@@ -616,51 +662,74 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
                        rank, channel, branch >> 1, bank,
                        rdwr ? "Write" : "Read", ras, cas);
 
+               switch (ce_errors) {
+               case FERR_NF_M17ERR:
+                       specific = "Correctable Non-Mirrored Demand Data ECC";
+                       break;
+               case FERR_NF_M18ERR:
+                       specific = "Correctable Mirrored Demand Data ECC";
+                       break;
+               case FERR_NF_M19ERR:
+                       specific = "Correctable Spare-Copy Data ECC";
+                       break;
+               case FERR_NF_M20ERR:
+                       specific = "Correctable Patrol Data ECC";
+                       break;
+               }
+
                /* Form out message */
                snprintf(msg, sizeof(msg),
                         "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d "
-                        "CAS=%d, CE Err=0x%x)", branch >> 1, bank,
-                        rdwr ? "Write" : "Read", ras, cas, ce_errors);
+                        "CAS=%d, CE Err=0x%x (%s))", branch >> 1, bank,
+                        rdwr ? "Write" : "Read", ras, cas, ce_errors,
+                        specific);
 
                /* Call the helper to output message */
                edac_mc_handle_fbd_ce(mci, rank, channel, msg);
        }
 
-       /* See if any of the thermal errors have fired */
-       misc_errors = allErrors & FERR_NF_THERMAL;
-       if (misc_errors) {
-               i5000_printk(KERN_WARNING, "\tTHERMAL Error, bits= 0x%x\n",
-                       misc_errors);
-       }
-
-       /* See if any of the thermal errors have fired */
-       misc_errors = allErrors & FERR_NF_NON_RETRY;
-       if (misc_errors) {
-               i5000_printk(KERN_WARNING, "\tNON-Retry  Errors, bits= 0x%x\n",
-                       misc_errors);
-       }
+       if (!misc_messages)
+               return;
 
-       /* See if any of the thermal errors have fired */
-       misc_errors = allErrors & FERR_NF_NORTH_CRC;
+       misc_errors = allErrors & (FERR_NF_NON_RETRY | FERR_NF_NORTH_CRC |
+                                  FERR_NF_SPD_PROTOCOL | FERR_NF_DIMM_SPARE);
        if (misc_errors) {
-               i5000_printk(KERN_WARNING,
-                       "\tNORTHBOUND CRC  Error, bits= 0x%x\n",
-                       misc_errors);
-       }
+               switch (misc_errors) {
+               case FERR_NF_M13ERR:
+                       specific = "Non-Retry or Redundant Retry FBD Memory "
+                                       "Alert or Redundant Fast Reset Timeout";
+                       break;
+               case FERR_NF_M14ERR:
+                       specific = "Non-Retry or Redundant Retry FBD "
+                                       "Configuration Alert";
+                       break;
+               case FERR_NF_M15ERR:
+                       specific = "Non-Retry or Redundant Retry FBD "
+                                       "Northbound CRC error on read data";
+                       break;
+               case FERR_NF_M21ERR:
+                       specific = "FBD Northbound CRC error on "
+                                       "FBD Sync Status";
+                       break;
+               case FERR_NF_M22ERR:
+                       specific = "SPD protocol error";
+                       break;
+               case FERR_NF_M27ERR:
+                       specific = "DIMM-spare copy started";
+                       break;
+               case FERR_NF_M28ERR:
+                       specific = "DIMM-spare copy completed";
+                       break;
+               }
+               branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd);
 
-       /* See if any of the thermal errors have fired */
-       misc_errors = allErrors & FERR_NF_SPD_PROTOCOL;
-       if (misc_errors) {
-               i5000_printk(KERN_WARNING,
-                       "\tSPD Protocol  Error, bits= 0x%x\n",
-                       misc_errors);
-       }
+               /* Form out message */
+               snprintf(msg, sizeof(msg),
+                        "(Branch=%d Err=%#x (%s))", branch >> 1,
+                        misc_errors, specific);
 
-       /* See if any of the thermal errors have fired */
-       misc_errors = allErrors & FERR_NF_DIMM_SPARE;
-       if (misc_errors) {
-               i5000_printk(KERN_WARNING, "\tDIMM-Spare  Error, bits= 0x%x\n",
-                       misc_errors);
+               /* Call the helper to output message */
+               edac_mc_handle_fbd_ce(mci, 0, 0, msg);
        }
 }
 
@@ -1497,3 +1566,6 @@ MODULE_DESCRIPTION("MC Driver for Intel I5000 memory controllers - "
 
 module_param(edac_op_state, int, 0444);
 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
+module_param(misc_messages, int, 0444);
+MODULE_PARM_DESC(misc_messages, "Log miscellaneous non fatal messages");
+
index c5305e3ee4346932b44cc73074cb6718bd3a38ad..577760a82a0f7d5519cd2631ccf1d7fd99f3ec05 100644 (file)
@@ -114,6 +114,12 @@ struct i82443bxgx_edacmc_error_info {
 
 static struct edac_pci_ctl_info *i82443bxgx_pci;
 
+static struct pci_dev *mci_pdev;       /* init dev: in case that AGP code has
+                                        * already registered driver
+                                        */
+
+static int i82443bxgx_registered = 1;
+
 static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci,
                                struct i82443bxgx_edacmc_error_info
                                *info)
@@ -345,10 +351,17 @@ EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
 static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
                                                const struct pci_device_id *ent)
 {
+       int rc;
+
        debugf0("MC: " __FILE__ ": %s()\n", __func__);
 
        /* don't need to call pci_device_enable() */
-       return i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
+       rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
+
+       if (mci_pdev == NULL)
+               mci_pdev = pci_dev_get(pdev);
+
+       return rc;
 }
 
 static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
@@ -387,15 +400,61 @@ static struct pci_driver i82443bxgx_edacmc_driver = {
 
 static int __init i82443bxgx_edacmc_init(void)
 {
+       int pci_rc;
        /* Ensure that the OPSTATE is set correctly for POLL or NMI */
        opstate_init();
 
-       return pci_register_driver(&i82443bxgx_edacmc_driver);
+       pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver);
+       if (pci_rc < 0)
+               goto fail0;
+
+       if (mci_pdev == NULL) {
+               const struct pci_device_id *id = &i82443bxgx_pci_tbl[0];
+               int i = 0;
+               i82443bxgx_registered = 0;
+
+               while (mci_pdev == NULL && id->vendor != 0) {
+                       mci_pdev = pci_get_device(id->vendor,
+                                       id->device, NULL);
+                       i++;
+                       id = &i82443bxgx_pci_tbl[i];
+               }
+               if (!mci_pdev) {
+                       debugf0("i82443bxgx pci_get_device fail\n");
+                       pci_rc = -ENODEV;
+                       goto fail1;
+               }
+
+               pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl);
+
+               if (pci_rc < 0) {
+                       debugf0("i82443bxgx init fail\n");
+                       pci_rc = -ENODEV;
+                       goto fail1;
+               }
+       }
+
+       return 0;
+
+fail1:
+       pci_unregister_driver(&i82443bxgx_edacmc_driver);
+
+fail0:
+       if (mci_pdev != NULL)
+               pci_dev_put(mci_pdev);
+
+       return pci_rc;
 }
 
 static void __exit i82443bxgx_edacmc_exit(void)
 {
        pci_unregister_driver(&i82443bxgx_edacmc_driver);
+
+       if (!i82443bxgx_registered)
+               i82443bxgx_edacmc_remove_one(mci_pdev);
+
+       if (mci_pdev)
+               pci_dev_put(mci_pdev);
 }
 
 module_init(i82443bxgx_edacmc_init);
index 2265d9ca1535652018fb9f28f87f3d7ba447231c..0cfcb2d075a0620228092f741970b525702319a7 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/mod_devicetable.h>
 #include <linux/edac.h>
+#include <linux/smp.h>
 
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
@@ -40,7 +41,7 @@ static u32 orig_pci_err_en;
 #endif
 
 static u32 orig_l2_err_disable;
-static u32 orig_hid1;
+static u32 orig_hid1[2];
 
 /************************ MC SYSFS parts ***********************************/
 
@@ -647,6 +648,9 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = {
        {
         .compatible = "fsl,8568-l2-cache-controller",
         },
+       {
+        .compatible = "fsl,mpc8572-l2-cache-controller",
+        },
        {},
 };
 
@@ -912,7 +916,8 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
                /* register interrupts */
                pdata->irq = irq_of_parse_and_map(op->node, 0);
                res = devm_request_irq(&op->dev, pdata->irq,
-                                      mpc85xx_mc_isr, IRQF_DISABLED,
+                                      mpc85xx_mc_isr,
+                                       IRQF_DISABLED | IRQF_SHARED,
                                       "[EDAC] MC err", mci);
                if (res < 0) {
                        printk(KERN_ERR "%s: Unable to request irq %d for "
@@ -980,6 +985,9 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
        {
         .compatible = "fsl,8568-memory-controller",
         },
+       {
+        .compatible = "fsl,mpc8572-memory-controller",
+        },
        {},
 };
 
@@ -995,6 +1003,14 @@ static struct of_platform_driver mpc85xx_mc_err_driver = {
                   },
 };
 
+
+static void __init mpc85xx_mc_clear_rfxe(void *data)
+{
+       orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1);
+       mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000));
+}
+
+
 static int __init mpc85xx_mc_init(void)
 {
        int res = 0;
@@ -1030,19 +1046,22 @@ static int __init mpc85xx_mc_init(void)
         * need to clear HID1[RFXE] to disable machine check int
         * so we can catch it
         */
-       if (edac_op_state == EDAC_OPSTATE_INT) {
-               orig_hid1 = mfspr(SPRN_HID1);
-               mtspr(SPRN_HID1, (orig_hid1 & ~0x20000));
-       }
+       if (edac_op_state == EDAC_OPSTATE_INT)
+               on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0);
 
        return 0;
 }
 
 module_init(mpc85xx_mc_init);
 
+static void __exit mpc85xx_mc_restore_hid1(void *data)
+{
+       mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]);
+}
+
 static void __exit mpc85xx_mc_exit(void)
 {
-       mtspr(SPRN_HID1, orig_hid1);
+       on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0);
 #ifdef CONFIG_PCI
        of_unregister_platform_driver(&mpc85xx_pci_err_driver);
 #endif
index bbd73a406e537106a2eeda4ba4a2ba1a543b030d..418c18f07e9d30af996bd4e01eada238e0318113 100644 (file)
@@ -189,39 +189,16 @@ static const char gap_count_table[] = {
        63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
 };
 
-struct bm_data {
-       struct fw_transaction t;
-       struct {
-               __be32 arg;
-               __be32 data;
-       } lock;
-       u32 old;
-       int rcode;
-       struct completion done;
-};
-
-static void
-complete_bm_lock(struct fw_card *card, int rcode,
-                void *payload, size_t length, void *data)
-{
-       struct bm_data *bmd = data;
-
-       if (rcode == RCODE_COMPLETE)
-               bmd->old = be32_to_cpu(*(__be32 *) payload);
-       bmd->rcode = rcode;
-       complete(&bmd->done);
-}
-
 static void
 fw_card_bm_work(struct work_struct *work)
 {
        struct fw_card *card = container_of(work, struct fw_card, work.work);
        struct fw_device *root_device;
        struct fw_node *root_node, *local_node;
-       struct bm_data bmd;
        unsigned long flags;
-       int root_id, new_root_id, irm_id, gap_count, generation, grace;
+       int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
        bool do_reset = false;
+       __be32 lock_data[2];
 
        spin_lock_irqsave(&card->lock, flags);
        local_node = card->local_node;
@@ -263,33 +240,28 @@ fw_card_bm_work(struct work_struct *work)
                        goto pick_me;
                }
 
-               bmd.lock.arg = cpu_to_be32(0x3f);
-               bmd.lock.data = cpu_to_be32(local_node->node_id);
+               lock_data[0] = cpu_to_be32(0x3f);
+               lock_data[1] = cpu_to_be32(local_node->node_id);
 
                spin_unlock_irqrestore(&card->lock, flags);
 
-               init_completion(&bmd.done);
-               fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP,
-                               irm_id, generation,
-                               SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
-                               &bmd.lock, sizeof(bmd.lock),
-                               complete_bm_lock, &bmd);
-               wait_for_completion(&bmd.done);
+               rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+                               irm_id, generation, SCODE_100,
+                               CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
+                               lock_data, sizeof(lock_data));
 
-               if (bmd.rcode == RCODE_GENERATION) {
-                       /*
-                        * Another bus reset happened. Just return,
-                        * the BM work has been rescheduled.
-                        */
+               if (rcode == RCODE_GENERATION)
+                       /* Another bus reset, BM work has been rescheduled. */
                        goto out;
-               }
 
-               if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f)
+               if (rcode == RCODE_COMPLETE &&
+                   lock_data[0] != cpu_to_be32(0x3f))
                        /* Somebody else is BM, let them do the work. */
                        goto out;
 
                spin_lock_irqsave(&card->lock, flags);
-               if (bmd.rcode != RCODE_COMPLETE) {
+
+               if (rcode != RCODE_COMPLETE) {
                        /*
                         * The lock request failed, maybe the IRM
                         * isn't really IRM capable after all. Let's
index 2e6d5848d2172011f94058b09c8634c56b091dea..ed03234cbea89ea2247b9d4d005d7e5d1baf1221 100644 (file)
@@ -720,8 +720,8 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
 #define GET_PAYLOAD_LENGTH(v)  ((v) & 0xffff)
 #define GET_INTERRUPT(v)       (((v) >> 16) & 0x01)
 #define GET_SKIP(v)            (((v) >> 17) & 0x01)
-#define GET_TAG(v)             (((v) >> 18) & 0x02)
-#define GET_SY(v)              (((v) >> 20) & 0x04)
+#define GET_TAG(v)             (((v) >> 18) & 0x03)
+#define GET_SY(v)              (((v) >> 20) & 0x0f)
 #define GET_HEADER_LENGTH(v)   (((v) >> 24) & 0xff)
 
 static int ioctl_queue_iso(struct client *client, void *buffer)
@@ -913,7 +913,7 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
                        return -EFAULT;
        }
 
-       return 0;
+       return retval;
 }
 
 static long
index 0855fb5568e806cf92546e466b73a702e9f55de6..3fccdd48410094a1bc99fe22e916d465d3ab191b 100644 (file)
@@ -381,46 +381,21 @@ static struct device_attribute fw_device_attributes[] = {
        __ATTR_NULL,
 };
 
-struct read_quadlet_callback_data {
-       struct completion done;
-       int rcode;
-       u32 data;
-};
-
-static void
-complete_transaction(struct fw_card *card, int rcode,
-                    void *payload, size_t length, void *data)
-{
-       struct read_quadlet_callback_data *callback_data = data;
-
-       if (rcode == RCODE_COMPLETE)
-               callback_data->data = be32_to_cpu(*(__be32 *)payload);
-       callback_data->rcode = rcode;
-       complete(&callback_data->done);
-}
-
 static int
 read_rom(struct fw_device *device, int generation, int index, u32 *data)
 {
-       struct read_quadlet_callback_data callback_data;
-       struct fw_transaction t;
-       u64 offset;
+       int rcode;
 
        /* device->node_id, accessed below, must not be older than generation */
        smp_rmb();
 
-       init_completion(&callback_data.done);
-
-       offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
-       fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
+       rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST,
                        device->node_id, generation, device->max_speed,
-                       offset, NULL, 4, complete_transaction, &callback_data);
-
-       wait_for_completion(&callback_data.done);
-
-       *data = callback_data.data;
+                       (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4,
+                       data, 4);
+       be32_to_cpus(data);
 
-       return callback_data.rcode;
+       return rcode;
 }
 
 #define READ_BIB_ROM_SIZE      256
index aaff50ebba1def2892a8945be8b9289d39921c4f..ef0b9b419c27a6cbdd4216916368641f3968df17 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/blkdev.h>
+#include <linux/bug.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
@@ -181,10 +182,16 @@ struct sbp2_target {
 #define SBP2_MAX_LOGIN_ORB_TIMEOUT     40000U  /* Timeout in ms */
 #define SBP2_ORB_TIMEOUT               2000U   /* Timeout in ms */
 #define SBP2_ORB_NULL                  0x80000000
-#define SBP2_MAX_SG_ELEMENT_LENGTH     0xf000
 #define SBP2_RETRY_LIMIT               0xf             /* 15 retries */
 #define SBP2_CYCLE_LIMIT               (0xc8 << 12)    /* 200 125us cycles */
 
+/*
+ * The default maximum s/g segment size of a FireWire controller is
+ * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
+ * be quadlet-aligned, we set the length limit to 0xffff & ~3.
+ */
+#define SBP2_MAX_SEG_SIZE              0xfffc
+
 /* Unit directory keys */
 #define SBP2_CSR_UNIT_CHARACTERISTICS  0x3a
 #define SBP2_CSR_FIRMWARE_REVISION     0x3c
@@ -621,25 +628,15 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
        return retval;
 }
 
-static void
-complete_agent_reset_write(struct fw_card *card, int rcode,
-                          void *payload, size_t length, void *done)
-{
-       complete(done);
-}
-
 static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-       DECLARE_COMPLETION_ONSTACK(done);
-       struct fw_transaction t;
-       static u32 z;
+       __be32 d = 0;
 
-       fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
-                       lu->tgt->node_id, lu->generation, device->max_speed,
-                       lu->command_block_agent_address + SBP2_AGENT_RESET,
-                       &z, sizeof(z), complete_agent_reset_write, &done);
-       wait_for_completion(&done);
+       fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
+                          lu->tgt->node_id, lu->generation, device->max_speed,
+                          lu->command_block_agent_address + SBP2_AGENT_RESET,
+                          &d, sizeof(d));
 }
 
 static void
@@ -653,7 +650,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
        struct fw_transaction *t;
-       static u32 z;
+       static __be32 d;
 
        t = kmalloc(sizeof(*t), GFP_ATOMIC);
        if (t == NULL)
@@ -662,7 +659,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
        fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
                        lu->tgt->node_id, lu->generation, device->max_speed,
                        lu->command_block_agent_address + SBP2_AGENT_RESET,
-                       &z, sizeof(z), complete_agent_reset_write_no_wait, t);
+                       &d, sizeof(d), complete_agent_reset_write_no_wait, t);
 }
 
 static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
@@ -823,13 +820,6 @@ static void sbp2_target_put(struct sbp2_target *tgt)
        kref_put(&tgt->kref, sbp2_release_target);
 }
 
-static void
-complete_set_busy_timeout(struct fw_card *card, int rcode,
-                         void *payload, size_t length, void *done)
-{
-       complete(done);
-}
-
 /*
  * Write retransmit retry values into the BUSY_TIMEOUT register.
  * - The single-phase retry protocol is supported by all SBP-2 devices, but the
@@ -849,17 +839,12 @@ complete_set_busy_timeout(struct fw_card *card, int rcode,
 static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-       DECLARE_COMPLETION_ONSTACK(done);
-       struct fw_transaction t;
-       static __be32 busy_timeout;
-
-       busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
+       __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
 
-       fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
-                       lu->tgt->node_id, lu->generation, device->max_speed,
-                       CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
-                       sizeof(busy_timeout), complete_set_busy_timeout, &done);
-       wait_for_completion(&done);
+       fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
+                          lu->tgt->node_id, lu->generation, device->max_speed,
+                          CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT,
+                          &d, sizeof(d));
 }
 
 static void sbp2_reconnect(struct work_struct *work);
@@ -1121,6 +1106,10 @@ static int sbp2_probe(struct device *dev)
        struct Scsi_Host *shost;
        u32 model, firmware_revision;
 
+       if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
+               BUG_ON(dma_set_max_seg_size(device->card->device,
+                                           SBP2_MAX_SEG_SIZE));
+
        shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
        if (shost == NULL)
                return -ENOMEM;
@@ -1369,14 +1358,12 @@ static int
 sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
                     struct sbp2_logical_unit *lu)
 {
-       struct scatterlist *sg;
-       int sg_len, l, i, j, count;
-       dma_addr_t sg_addr;
-
-       sg = scsi_sglist(orb->cmd);
-       count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
-                          orb->cmd->sc_data_direction);
-       if (count == 0)
+       struct scatterlist *sg = scsi_sglist(orb->cmd);
+       int i, n;
+
+       n = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
+                      orb->cmd->sc_data_direction);
+       if (n == 0)
                goto fail;
 
        /*
@@ -1386,7 +1373,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
         * as the second generation iPod which doesn't support page
         * tables.
         */
-       if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
+       if (n == 1) {
                orb->request.data_descriptor.high =
                        cpu_to_be32(lu->tgt->address_high);
                orb->request.data_descriptor.low  =
@@ -1396,29 +1383,9 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
                return 0;
        }
 
-       /*
-        * Convert the scatterlist to an sbp2 page table.  If any
-        * scatterlist entries are too big for sbp2, we split them as we
-        * go.  Even if we ask the block I/O layer to not give us sg
-        * elements larger than 65535 bytes, some IOMMUs may merge sg elements
-        * during DMA mapping, and Linux currently doesn't prevent this.
-        */
-       for (i = 0, j = 0; i < count; i++, sg = sg_next(sg)) {
-               sg_len = sg_dma_len(sg);
-               sg_addr = sg_dma_address(sg);
-               while (sg_len) {
-                       /* FIXME: This won't get us out of the pinch. */
-                       if (unlikely(j >= ARRAY_SIZE(orb->page_table))) {
-                               fw_error("page table overflow\n");
-                               goto fail_page_table;
-                       }
-                       l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
-                       orb->page_table[j].low = cpu_to_be32(sg_addr);
-                       orb->page_table[j].high = cpu_to_be32(l << 16);
-                       sg_addr += l;
-                       sg_len -= l;
-                       j++;
-               }
+       for_each_sg(sg, sg, n, i) {
+               orb->page_table[i].high = cpu_to_be32(sg_dma_len(sg) << 16);
+               orb->page_table[i].low = cpu_to_be32(sg_dma_address(sg));
        }
 
        orb->page_table_bus =
@@ -1437,13 +1404,13 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
        orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high);
        orb->request.data_descriptor.low  = cpu_to_be32(orb->page_table_bus);
        orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT |
-                                        COMMAND_ORB_DATA_SIZE(j));
+                                        COMMAND_ORB_DATA_SIZE(n));
 
        return 0;
 
  fail_page_table:
-       dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
-                    orb->cmd->sc_data_direction);
+       dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
+                    scsi_sg_count(orb->cmd), orb->cmd->sc_data_direction);
  fail:
        return -ENOMEM;
 }
@@ -1456,7 +1423,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
        struct sbp2_command_orb *orb;
        unsigned int max_payload;
-       int retval = SCSI_MLQUEUE_HOST_BUSY;
+       int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
 
        /*
         * Bidirectional commands are not yet implemented, and unknown
@@ -1500,6 +1467,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        if (cmd->sc_data_direction == DMA_FROM_DEVICE)
                orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION);
 
+       generation = device->generation;
+       smp_rmb();    /* sbp2_map_scatterlist looks at tgt->address_high */
+
        if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
                goto out;
 
@@ -1512,7 +1482,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        if (dma_mapping_error(device->card->device, orb->base.request_bus))
                goto out;
 
-       sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation,
+       sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation,
                      lu->command_block_agent_address + SBP2_ORB_POINTER);
        retval = 0;
  out:
@@ -1564,6 +1534,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
        if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
                blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
 
+       blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
+
        return 0;
 }
 
index e5d1a0b64fcf1b714a186d31a8b7aabf90e7aa97..022ac4fabb6740d3fec872142e9d65d1bc001a96 100644 (file)
@@ -247,7 +247,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
  */
 void
 fw_send_request(struct fw_card *card, struct fw_transaction *t,
-               int tcode, int node_id, int generation, int speed,
+               int tcode, int destination_id, int generation, int speed,
                unsigned long long offset,
                void *payload, size_t length,
                fw_transaction_callback_t callback, void *callback_data)
@@ -279,13 +279,14 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
        card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
        card->tlabel_mask |= (1 << tlabel);
 
-       t->node_id = node_id;
+       t->node_id = destination_id;
        t->tlabel = tlabel;
        t->callback = callback;
        t->callback_data = callback_data;
 
-       fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id,
-                       generation, speed, offset, payload, length);
+       fw_fill_request(&t->packet, tcode, t->tlabel,
+                       destination_id, card->node_id, generation,
+                       speed, offset, payload, length);
        t->packet.callback = transmit_complete_callback;
 
        list_add_tail(&t->link, &card->transaction_list);
@@ -296,6 +297,45 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
 }
 EXPORT_SYMBOL(fw_send_request);
 
+struct transaction_callback_data {
+       struct completion done;
+       void *payload;
+       int rcode;
+};
+
+static void transaction_callback(struct fw_card *card, int rcode,
+                                void *payload, size_t length, void *data)
+{
+       struct transaction_callback_data *d = data;
+
+       if (rcode == RCODE_COMPLETE)
+               memcpy(d->payload, payload, length);
+       d->rcode = rcode;
+       complete(&d->done);
+}
+
+/**
+ * fw_run_transaction - send request and sleep until transaction is completed
+ *
+ * Returns the RCODE.
+ */
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+               int generation, int speed, unsigned long long offset,
+               void *data, size_t length)
+{
+       struct transaction_callback_data d;
+       struct fw_transaction t;
+
+       init_completion(&d.done);
+       d.payload = data;
+       fw_send_request(card, &t, tcode, destination_id, generation, speed,
+                       offset, data, length, transaction_callback, &d);
+       wait_for_completion(&d.done);
+
+       return d.rcode;
+}
+EXPORT_SYMBOL(fw_run_transaction);
+
 static DEFINE_MUTEX(phy_config_mutex);
 static DECLARE_COMPLETION(phy_config_done);
 
index 2ae1b0d6cb7bdfaa6929ccc06a00d63501acebcf..027f58ce81ad124a03b630071cd94dc1d4579348 100644 (file)
@@ -426,11 +426,14 @@ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
 
 void
 fw_send_request(struct fw_card *card, struct fw_transaction *t,
-               int tcode, int node_id, int generation, int speed,
-               unsigned long long offset,
-               void *data, size_t length,
+               int tcode, int destination_id, int generation, int speed,
+               unsigned long long offset, void *data, size_t length,
                fw_transaction_callback_t callback, void *callback_data);
 
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+                      int generation, int speed, unsigned long long offset,
+                      void *data, size_t length);
+
 int fw_cancel_transaction(struct fw_card *card,
                          struct fw_transaction *transaction);
 
index b91ef63126ede7decff0bdbbbd475f03a07bd219..deb154aa47c412be66f4ee68281f053cf7a4c241 100644 (file)
@@ -334,9 +334,9 @@ static void ibft_release(struct kobject *kobj)
 /*
  *  Routines for parsing the iBFT data to be human readable.
  */
-ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
-                                 struct ibft_attribute *attr,
-                                 char *buf)
+static ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
+                                       struct ibft_attribute *attr,
+                                       char *buf)
 {
        struct ibft_initiator *initiator = entry->initiator;
        void *ibft_loc = entry->header;
@@ -376,9 +376,9 @@ ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
        return str - buf;
 }
 
-ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
-                           struct ibft_attribute *attr,
-                           char *buf)
+static ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
+                                 struct ibft_attribute *attr,
+                                 char *buf)
 {
        struct ibft_nic *nic = entry->nic;
        void *ibft_loc = entry->header;
@@ -440,9 +440,9 @@ ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
        return str - buf;
 };
 
-ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
-                              struct ibft_attribute *attr,
-                              char *buf)
+static ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
+                                    struct ibft_attribute *attr,
+                                    char *buf)
 {
        struct ibft_tgt *tgt = entry->tgt;
        void *ibft_loc = entry->header;
index 8d2940517c99221c33e3bf200ac53a82214cebee..9112830107a53d4c208b5a8cbf1934026549bac1 100644 (file)
@@ -67,17 +67,28 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
  * when setting direction, and otherwise illegal.  Until board setup code
  * and drivers use explicit requests everywhere (which won't happen when
  * those calls have no teeth) we can't avoid autorequesting.  This nag
- * message should motivate switching to explicit requests...
+ * message should motivate switching to explicit requests... so should
+ * the weaker cleanup after faults, compared to gpio_request().
  */
-static void gpio_ensure_requested(struct gpio_desc *desc)
+static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
 {
        if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
-               pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc));
+               struct gpio_chip *chip = desc->chip;
+               int gpio = chip->base + offset;
+
+               if (!try_module_get(chip->owner)) {
+                       pr_err("GPIO-%d: module can't be gotten \n", gpio);
+                       clear_bit(FLAG_REQUESTED, &desc->flags);
+                       /* lose */
+                       return -EIO;
+               }
+               pr_warning("GPIO-%d autorequested\n", gpio);
                desc_set_label(desc, "[auto]");
-               if (!try_module_get(desc->chip->owner))
-                       pr_err("GPIO-%d: module can't be gotten \n",
-                                       (int)(desc - gpio_desc));
+               /* caller must chip->request() w/o spinlock */
+               if (chip->request)
+                       return 1;
        }
+       return 0;
 }
 
 /* caller holds gpio_lock *OR* gpio is marked as requested */
@@ -752,6 +763,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove);
 int gpio_request(unsigned gpio, const char *label)
 {
        struct gpio_desc        *desc;
+       struct gpio_chip        *chip;
        int                     status = -EINVAL;
        unsigned long           flags;
 
@@ -760,14 +772,15 @@ int gpio_request(unsigned gpio, const char *label)
        if (!gpio_is_valid(gpio))
                goto done;
        desc = &gpio_desc[gpio];
-       if (desc->chip == NULL)
+       chip = desc->chip;
+       if (chip == NULL)
                goto done;
 
-       if (!try_module_get(desc->chip->owner))
+       if (!try_module_get(chip->owner))
                goto done;
 
        /* NOTE:  gpio_request() can be called in early boot,
-        * before IRQs are enabled.
+        * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
         */
 
        if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
@@ -775,7 +788,20 @@ int gpio_request(unsigned gpio, const char *label)
                status = 0;
        } else {
                status = -EBUSY;
-               module_put(desc->chip->owner);
+               module_put(chip->owner);
+       }
+
+       if (chip->request) {
+               /* chip->request may sleep */
+               spin_unlock_irqrestore(&gpio_lock, flags);
+               status = chip->request(chip, gpio - chip->base);
+               spin_lock_irqsave(&gpio_lock, flags);
+
+               if (status < 0) {
+                       desc_set_label(desc, NULL);
+                       module_put(chip->owner);
+                       clear_bit(FLAG_REQUESTED, &desc->flags);
+               }
        }
 
 done:
@@ -791,6 +817,9 @@ void gpio_free(unsigned gpio)
 {
        unsigned long           flags;
        struct gpio_desc        *desc;
+       struct gpio_chip        *chip;
+
+       might_sleep();
 
        if (!gpio_is_valid(gpio)) {
                WARN_ON(extra_checks);
@@ -802,9 +831,17 @@ void gpio_free(unsigned gpio)
        spin_lock_irqsave(&gpio_lock, flags);
 
        desc = &gpio_desc[gpio];
-       if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) {
+       chip = desc->chip;
+       if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {
+               if (chip->free) {
+                       spin_unlock_irqrestore(&gpio_lock, flags);
+                       might_sleep_if(extra_checks && chip->can_sleep);
+                       chip->free(chip, gpio - chip->base);
+                       spin_lock_irqsave(&gpio_lock, flags);
+               }
                desc_set_label(desc, NULL);
                module_put(desc->chip->owner);
+               clear_bit(FLAG_REQUESTED, &desc->flags);
        } else
                WARN_ON(extra_checks);
 
@@ -869,7 +906,9 @@ int gpio_direction_input(unsigned gpio)
        gpio -= chip->base;
        if (gpio >= chip->ngpio)
                goto fail;
-       gpio_ensure_requested(desc);
+       status = gpio_ensure_requested(desc, gpio);
+       if (status < 0)
+               goto fail;
 
        /* now we know the gpio is valid and chip won't vanish */
 
@@ -877,9 +916,22 @@ int gpio_direction_input(unsigned gpio)
 
        might_sleep_if(extra_checks && chip->can_sleep);
 
+       if (status) {
+               status = chip->request(chip, gpio);
+               if (status < 0) {
+                       pr_debug("GPIO-%d: chip request fail, %d\n",
+                               chip->base + gpio, status);
+                       /* and it's not available to anyone else ...
+                        * gpio_request() is the fully clean solution.
+                        */
+                       goto lose;
+               }
+       }
+
        status = chip->direction_input(chip, gpio);
        if (status == 0)
                clear_bit(FLAG_IS_OUT, &desc->flags);
+lose:
        return status;
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
@@ -907,7 +959,9 @@ int gpio_direction_output(unsigned gpio, int value)
        gpio -= chip->base;
        if (gpio >= chip->ngpio)
                goto fail;
-       gpio_ensure_requested(desc);
+       status = gpio_ensure_requested(desc, gpio);
+       if (status < 0)
+               goto fail;
 
        /* now we know the gpio is valid and chip won't vanish */
 
@@ -915,9 +969,22 @@ int gpio_direction_output(unsigned gpio, int value)
 
        might_sleep_if(extra_checks && chip->can_sleep);
 
+       if (status) {
+               status = chip->request(chip, gpio);
+               if (status < 0) {
+                       pr_debug("GPIO-%d: chip request fail, %d\n",
+                               chip->base + gpio, status);
+                       /* and it's not available to anyone else ...
+                        * gpio_request() is the fully clean solution.
+                        */
+                       goto lose;
+               }
+       }
+
        status = chip->direction_output(chip, gpio, value);
        if (status == 0)
                set_bit(FLAG_IS_OUT, &desc->flags);
+lose:
        return status;
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
@@ -1008,6 +1075,24 @@ int __gpio_cansleep(unsigned gpio)
 }
 EXPORT_SYMBOL_GPL(__gpio_cansleep);
 
+/**
+ * __gpio_to_irq() - return the IRQ corresponding to a GPIO
+ * @gpio: gpio whose IRQ will be returned (already requested)
+ * Context: any
+ *
+ * This is used directly or indirectly to implement gpio_to_irq().
+ * It returns the number of the IRQ signaled by this (input) GPIO,
+ * or a negative errno.
+ */
+int __gpio_to_irq(unsigned gpio)
+{
+       struct gpio_chip        *chip;
+
+       chip = gpio_to_chip(gpio);
+       return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO;
+}
+EXPORT_SYMBOL_GPL(__gpio_to_irq);
+
 
 
 /* There's no value in making it easy to inline GPIO calls that may sleep.
index 39c795ad8312283caf2145139dc6f4d088b51227..8b24d784db93e6bfda3e9b28440c10caab8173fa 100644 (file)
@@ -255,10 +255,6 @@ static int __devinit max7301_probe(struct spi_device *spi)
        ts->chip.dev = &spi->dev;
        ts->chip.owner = THIS_MODULE;
 
-       ret = gpiochip_add(&ts->chip);
-       if (ret)
-               goto exit_destroy;
-
        /*
         * tristate all pins in hardware and cache the
         * register values for later use.
@@ -269,17 +265,19 @@ static int __devinit max7301_probe(struct spi_device *spi)
                max7301_write(spi, 0x08 + i, 0xAA);
                ts->port_config[i] = 0xAA;
                for (j = 0; j < 4; j++) {
-                       int idx = ts->chip.base + (i - 1) * 4 + j;
-                       ret = gpio_direction_input(idx);
+                       int offset = (i - 1) * 4 + j;
+                       ret = max7301_direction_input(&ts->chip, offset);
                        if (ret)
-                               goto exit_remove;
-                       gpio_free(idx);
+                               goto exit_destroy;
                }
        }
+
+       ret = gpiochip_add(&ts->chip);
+       if (ret)
+               goto exit_destroy;
+
        return ret;
 
-exit_remove:
-       gpiochip_remove(&ts->chip);
 exit_destroy:
        dev_set_drvdata(&spi->dev, NULL);
        mutex_destroy(&ts->lock);
@@ -325,13 +323,15 @@ static int __init max7301_init(void)
 {
        return spi_register_driver(&max7301_driver);
 }
+/* register after spi postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(max7301_init);
 
 static void __exit max7301_exit(void)
 {
        spi_unregister_driver(&max7301_driver);
 }
-
-module_init(max7301_init);
 module_exit(max7301_exit);
 
 MODULE_AUTHOR("Juergen Beisert");
index b51c8135ca284c8bfd229b763ccd68e45e1b4ae8..55ae9a41897aafe0db3da8d2fde1e7a7aec174d9 100644 (file)
@@ -372,7 +372,10 @@ static int __init max732x_init(void)
 {
        return i2c_add_driver(&max732x_driver);
 }
-module_init(max732x_init);
+/* register after i2c postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(max732x_init);
 
 static void __exit max732x_exit(void)
 {
index 8a1b405fefda040f0001a5799299eefbe55f5768..89c1d222e9d10b89b8acc56dbfff0b1933f1a2c3 100644 (file)
@@ -419,7 +419,10 @@ static int __init mcp23s08_init(void)
 {
        return spi_register_driver(&mcp23s08_driver);
 }
-module_init(mcp23s08_init);
+/* register after spi postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(mcp23s08_init);
 
 static void __exit mcp23s08_exit(void)
 {
index cc8468692ae0967b295e196c5073fb102c4894c7..9ceeb89f1325ea776bf47c1e89fbcb5b81b8eeec 100644 (file)
@@ -289,7 +289,10 @@ static int __init pca953x_init(void)
 {
        return i2c_add_driver(&pca953x_driver);
 }
-module_init(pca953x_init);
+/* register after i2c postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(pca953x_init);
 
 static void __exit pca953x_exit(void)
 {
index fc9c6ae739ee74f8f77b8836bd5e7894001e5d9d..4bc2070dd4a1010b498d63b96926e0cdbec69111 100644 (file)
@@ -351,7 +351,10 @@ static int __init pcf857x_init(void)
 {
        return i2c_add_driver(&pcf857x_driver);
 }
-module_init(pcf857x_init);
+/* register after i2c postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(pcf857x_init);
 
 static void __exit pcf857x_exit(void)
 {
index 88974342933c62f253d7406c33989b152014b8b8..9ac4720e647b2e2b026791d3d96d24ee2ef226a2 100644 (file)
@@ -517,7 +517,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
        RING_LOCALS;
 
        DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
-                 __FUNCTION__,
+                 __func__,
                  dev_priv->current_page,
                  dev_priv->sarea_priv->pf_current_page);
 
@@ -642,7 +642,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
 static int i915_flip_bufs(struct drm_device *dev, void *data,
                          struct drm_file *file_priv)
 {
-       DRM_DEBUG("%s\n", __FUNCTION__);
+       DRM_DEBUG("%s\n", __func__);
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
index da64108de775062b8f02c5f21a4d7749ba8a603c..f5999a91614e668aade684ccbb89fcaf5e1eba86 100644 (file)
@@ -17,25 +17,6 @@ config HID
        tristate "Generic HID support"
        depends on INPUT
        default y
-        select HID_A4TECH if !EMBEDDED
-        select HID_APPLE if !EMBEDDED
-        select HID_BELKIN if !EMBEDDED
-        select HID_BRIGHT if !EMBEDDED
-        select HID_CHERRY if !EMBEDDED
-        select HID_CHICONY if !EMBEDDED
-        select HID_CYPRESS if !EMBEDDED
-        select HID_DELL if !EMBEDDED
-        select HID_EZKEY if !EMBEDDED
-        select HID_GYRATION if !EMBEDDED
-        select HID_LOGITECH if !EMBEDDED
-        select HID_MICROSOFT if !EMBEDDED
-        select HID_MONTEREY if !EMBEDDED
-        select HID_PANTHERLORD if !EMBEDDED
-        select HID_PETALYNX if !EMBEDDED
-        select HID_SAMSUNG if !EMBEDDED
-        select HID_SONY if !EMBEDDED
-        select HID_SUNPLUS if !EMBEDDED
-
        ---help---
          A human interface device (HID) is a type of computer device that
          interacts directly with and takes input from humans. The term "HID"
@@ -102,89 +83,86 @@ config HID_COMPAT
        If unsure, say Y.
 
 config HID_A4TECH
-       tristate "A4 tech"
-       default m
+       tristate "A4 tech" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for A4 tech X5 and WOP-35 / Trust 450L mice.
 
 config HID_APPLE
-       tristate "Apple"
-       default m
+       tristate "Apple" if EMBEDDED
        depends on (USB_HID || BT_HIDP)
+       default y
        ---help---
        Support for some Apple devices which less or more break
        HID specification.
 
-       Say Y here if you want support for the special keys (Fn, Numlock) on
-       Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB
-       keyboards.
-
-       If unsure, say M.
+       Say Y here if you want support for keyboards of Apple iBooks, PowerBooks,
+       MacBooks, MacBook Pros and Apple Aluminum.
 
 config HID_BELKIN
-       tristate "Belkin"
-       default m
+       tristate "Belkin" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for Belkin Flip KVM and Wireless keyboard.
 
 config HID_BRIGHT
-       tristate "Bright"
-       default m
+       tristate "Bright" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for Bright ABNT-2 keyboard.
 
 config HID_CHERRY
-       tristate "Cherry"
-       default m
+       tristate "Cherry" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Cherry Cymotion.
+       Support for Cherry Cymotion keyboard.
 
 config HID_CHICONY
-       tristate "Chicony"
-       default m
+       tristate "Chicony" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for Chicony Tactical pad.
 
 config HID_CYPRESS
-       tristate "Cypress"
-       default m
+       tristate "Cypress" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Cypress mouse and barcodes.
+       Support for cypress mouse and barcode readers.
 
 config HID_DELL
-       tristate "Dell"
-       default m
+       tristate "Dell" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Dell W7658.
+       Support for quirky Dell HID hardware that require
+       special LED handling (W7658 and SK8115 models)
 
 config HID_EZKEY
-       tristate "Ezkey"
-       default m
+       tristate "Ezkey" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Ezkey mouse and barcodes.
+       Support for Ezkey BTC 8193 keyboard.
 
 config HID_GYRATION
-       tristate "Gyration"
-       default m
+       tristate "Gyration" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Gyration remote.
+       Support for Gyration remote control.
 
 config HID_LOGITECH
-       tristate "Logitech"
-       default m
+       tristate "Logitech" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for some Logitech devices which breaks less or more
-       HID specification.
+       Support for Logitech devices that are not fully compliant with HID standard.
 
 config LOGITECH_FF
        bool "Logitech force feedback"
@@ -211,28 +189,26 @@ config LOGIRUMBLEPAD2_FF
          Rumblepad 2 devices.
 
 config HID_MICROSOFT
-       tristate "Microsoft"
-       default m
+       tristate "Microsoft" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for some Microsoft devices which breaks less or more
-       HID specification.
+       Support for Microsoft devices that are not fully compliant with HID standard.
 
 config HID_MONTEREY
-       tristate "Monterey"
-       default m
+       tristate "Monterey" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for Monterey Genius KB29E.
 
 config HID_PANTHERLORD
-       tristate "Pantherlord devices support"
-       default m
+       tristate "Pantherlord devices support" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for PantherLord/GreenAsia based device support.
 
-
 config PANTHERLORD_FF
        bool "Pantherlord force feedback support"
        depends on HID_PANTHERLORD
@@ -242,32 +218,32 @@ config PANTHERLORD_FF
          or adapter and want to enable force feedback support for it.
 
 config HID_PETALYNX
-       tristate "Petalynx"
-       default m
+       tristate "Petalynx" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Petalynx Maxter remote.
+       Support for Petalynx Maxter remote control.
 
 config HID_SAMSUNG
-       tristate "Samsung"
-       default m
+       tristate "Samsung" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Samsung IR remote.
+       Support for Samsung InfraRed remote control.
 
 config HID_SONY
-       tristate "Sony"
-       default m
+       tristate "Sony" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
        Support for Sony PS3 controller.
 
 config HID_SUNPLUS
-       tristate "Sunplus"
-       default m
+       tristate "Sunplus" if EMBEDDED
        depends on USB_HID
+       default y
        ---help---
-       Support for Sunplus WDesktop input device.
+       Support for Sunplus wireless desktop.
 
 config THRUSTMASTER_FF
        tristate "ThrustMaster devices support"
index 8a7d9dbb4d07244b631458e024cbfe6fe21b39c6..721a36d97582010674e5a4c81faf0be457441d18 100644 (file)
@@ -1518,6 +1518,8 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
index aad9ed1b406e0dd5d028e74bbdc518b2effc326e..d9a1ba920c238f5e188353049ea3825985b6adcb 100644 (file)
 
 #define USB_VENDOR_ID_SOUNDGRAPH       0x15c2
 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD      0x0038
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2     0x0036
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3     0x0034
 
 #define USB_VENDOR_ID_SUN              0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE       0xcdab
index 497e0d1dd3c374c7f65129a487f11bb4c807364a..af3edb98df435f2c3fa22fde81350d4f15dcd286 100644 (file)
@@ -326,9 +326,8 @@ int hidraw_connect(struct hid_device *hid)
                goto out;
        }
 
-       dev->dev = device_create_drvdata(hidraw_class, NULL,
-                                        MKDEV(hidraw_major, minor), NULL,
-                                        "%s%d", "hidraw", minor);
+       dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor),
+                                NULL, "%s%d", "hidraw", minor);
 
        if (IS_ERR(dev->dev)) {
                spin_lock(&minors_lock);
index a6221e5dd984292613634a6ddf28c775615e6465..221ef6915a5f74ec06a6ab4e7969f17ae3e90d4b 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
-#include <asm/of_device.h>
+#include <linux/of_device.h>
 
 enum ams_irq {
        AMS_IRQ_FREEFALL = 0x01,
index 7321a88a51128adef8ba40016e03f0648b7e4a97..076a59cdabe9f7a205cedd3883d40416e2e9b9c7 100644 (file)
@@ -55,8 +55,8 @@ again:
                return ERR_PTR(err);
 
        id = id & MAX_ID_MASK;
-       hwdev = device_create_drvdata(hwmon_class, dev, MKDEV(0, 0), NULL,
-                                     HWMON_ID_FORMAT, id);
+       hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL,
+                             HWMON_ID_FORMAT, id);
 
        if (IS_ERR(hwdev)) {
                spin_lock(&idr_lock);
index 27443f073bc97f668dec983ac287e598a763f2d6..a9a45fcc85447575669593d70d9aaf6aaf5a3375 100644 (file)
@@ -312,7 +312,6 @@ static struct i2c_adapter mpc_ops = {
        .name = "MPC adapter",
        .id = I2C_HW_MPC107,
        .algo = &mpc_algo,
-       .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .timeout = 1,
 };
 
index e7eb7bf9ddecc762e088d17f155c5b38818c6a57..608038d64f81e7b6f0856fcad9b2faeae6fa830e 100644 (file)
@@ -589,11 +589,16 @@ omap_i2c_probe(struct platform_device *pdev)
 
        dev->dev = &pdev->dev;
        dev->irq = irq->start;
-       dev->base = (void __iomem *) IO_ADDRESS(mem->start);
+       dev->base = ioremap(mem->start, mem->end - mem->start + 1);
+       if (!dev->base) {
+               r = -ENOMEM;
+               goto err_free_mem;
+       }
+
        platform_set_drvdata(pdev, dev);
 
        if ((r = omap_i2c_get_clocks(dev)) != 0)
-               goto err_free_mem;
+               goto err_iounmap;
 
        omap_i2c_unidle(dev);
 
@@ -640,6 +645,8 @@ err_unuse_clocks:
        omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
        omap_i2c_idle(dev);
        omap_i2c_put_clocks(dev);
+err_iounmap:
+       iounmap(dev->base);
 err_free_mem:
        platform_set_drvdata(pdev, NULL);
        kfree(dev);
@@ -661,6 +668,7 @@ omap_i2c_remove(struct platform_device *pdev)
        i2c_del_adapter(&dev->adapter);
        omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
        omap_i2c_put_clocks(dev);
+       iounmap(dev->base);
        kfree(dev);
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(mem->start, (mem->end - mem->start) + 1);
index f80df9ae50541936925752804e632f901dcd4d3f..9eb76268ec782e81da477a2a25f6c849c18fc501 100644 (file)
@@ -126,7 +126,7 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
 
        dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
 
-#ifdef CONFIG_PPC_MERGE
+#ifdef CONFIG_PPC
        if (check_legacy_ioport(base)) {
                dev_err(dev, "I/O address %#08lx is not available\n", base);
                goto out;
index a95cb9465d656949bed4429279a75c35fb547b23..17356827b93d6ad571f08ca75d58bc6b9dec5426 100644 (file)
@@ -172,4 +172,15 @@ config MENELAUS
          and other features that are often used in portable devices like
          cell phones and PDAs.
 
+config MCU_MPC8349EMITX
+       tristate "MPC8349E-mITX MCU driver"
+       depends on I2C && PPC_83xx
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         Say Y here to enable soft power-off functionality on the Freescale
+         boards with the MPC8349E-mITX-compatible MCU chips. This driver will
+         also register MCU GPIOs with the generic GPIO API, so you'll able
+         to use MCU pins as GPIOs.
+
 endmenu
index 39e3e69ed1256bf93de0be16b9687bd15eb8e4a9..ca520fa143d696dd849e80792213ce796e0266a4 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_ISP1301_OMAP)    += isp1301_omap.o
 obj-$(CONFIG_TPS65010)         += tps65010.o
 obj-$(CONFIG_MENELAUS)         += menelaus.o
 obj-$(CONFIG_SENSORS_TSL2550)  += tsl2550.o
+obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/mcu_mpc8349emitx.c b/drivers/i2c/chips/mcu_mpc8349emitx.c
new file mode 100644 (file)
index 0000000..82a9bcb
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU
+ *
+ * Copyright (c) 2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+
+/*
+ * I don't have specifications for the MCU firmware, I found this register
+ * and bits positions by the trial&error method.
+ */
+#define MCU_REG_CTRL   0x20
+#define MCU_CTRL_POFF  0x40
+
+#define MCU_NUM_GPIO   2
+
+struct mcu {
+       struct mutex lock;
+       struct device_node *np;
+       struct i2c_client *client;
+       struct of_gpio_chip of_gc;
+       u8 reg_ctrl;
+};
+
+static struct mcu *glob_mcu;
+
+static void mcu_power_off(void)
+{
+       struct mcu *mcu = glob_mcu;
+
+       pr_info("Sending power-off request to the MCU...\n");
+       mutex_lock(&mcu->lock);
+       i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL,
+                                 mcu->reg_ctrl | MCU_CTRL_POFF);
+       mutex_unlock(&mcu->lock);
+}
+
+static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
+       struct mcu *mcu = container_of(of_gc, struct mcu, of_gc);
+       u8 bit = 1 << (4 + gpio);
+
+       mutex_lock(&mcu->lock);
+       if (val)
+               mcu->reg_ctrl &= ~bit;
+       else
+               mcu->reg_ctrl |= bit;
+
+       i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl);
+       mutex_unlock(&mcu->lock);
+}
+
+static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       mcu_gpio_set(gc, gpio, val);
+       return 0;
+}
+
+static int mcu_gpiochip_add(struct mcu *mcu)
+{
+       struct device_node *np;
+       struct of_gpio_chip *of_gc = &mcu->of_gc;
+       struct gpio_chip *gc = &of_gc->gc;
+       int ret;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx");
+       if (!np)
+               return -ENODEV;
+
+       gc->owner = THIS_MODULE;
+       gc->label = np->full_name;
+       gc->can_sleep = 1;
+       gc->ngpio = MCU_NUM_GPIO;
+       gc->base = -1;
+       gc->set = mcu_gpio_set;
+       gc->direction_output = mcu_gpio_dir_out;
+       of_gc->gpio_cells = 2;
+       of_gc->xlate = of_gpio_simple_xlate;
+
+       np->data = of_gc;
+       mcu->np = np;
+
+       /*
+        * We don't want to lose the node, its ->data and ->full_name...
+        * So, if succeeded, we don't put the node here.
+        */
+       ret = gpiochip_add(gc);
+       if (ret)
+               of_node_put(np);
+       return ret;
+}
+
+static int mcu_gpiochip_remove(struct mcu *mcu)
+{
+       int ret;
+
+       ret = gpiochip_remove(&mcu->of_gc.gc);
+       if (ret)
+               return ret;
+       of_node_put(mcu->np);
+
+       return 0;
+}
+
+static int __devinit mcu_probe(struct i2c_client *client,
+                              const struct i2c_device_id *id)
+{
+       struct mcu *mcu;
+       int ret;
+
+       mcu = kzalloc(sizeof(*mcu), GFP_KERNEL);
+       if (!mcu)
+               return -ENOMEM;
+
+       mutex_init(&mcu->lock);
+       mcu->client = client;
+       i2c_set_clientdata(client, mcu);
+
+       ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL);
+       if (ret < 0)
+               goto err;
+       mcu->reg_ctrl = ret;
+
+       ret = mcu_gpiochip_add(mcu);
+       if (ret)
+               goto err;
+
+       /* XXX: this is potentially racy, but there is no lock for ppc_md */
+       if (!ppc_md.power_off) {
+               glob_mcu = mcu;
+               ppc_md.power_off = mcu_power_off;
+               dev_info(&client->dev, "will provide power-off service\n");
+       }
+
+       return 0;
+err:
+       kfree(mcu);
+       return ret;
+}
+
+static int __devexit mcu_remove(struct i2c_client *client)
+{
+       struct mcu *mcu = i2c_get_clientdata(client);
+       int ret;
+
+       if (glob_mcu == mcu) {
+               ppc_md.power_off = NULL;
+               glob_mcu = NULL;
+       }
+
+       ret = mcu_gpiochip_remove(mcu);
+       if (ret)
+               return ret;
+       i2c_set_clientdata(client, NULL);
+       kfree(mcu);
+       return 0;
+}
+
+static const struct i2c_device_id mcu_ids[] = {
+       { "mcu-mpc8349emitx", },
+       {},
+};
+MODULE_DEVICE_TABLE(i2c, mcu_ids);
+
+static struct i2c_driver mcu_driver = {
+       .driver = {
+               .name = "mcu-mpc8349emitx",
+               .owner = THIS_MODULE,
+       },
+       .probe = mcu_probe,
+       .remove = __devexit_p(mcu_remove),
+       .id_table = mcu_ids,
+};
+
+static int __init mcu_init(void)
+{
+       return i2c_add_driver(&mcu_driver);
+}
+module_init(mcu_init);
+
+static void __exit mcu_exit(void)
+{
+       i2c_del_driver(&mcu_driver);
+}
+module_exit(mcu_exit);
+
+MODULE_DESCRIPTION("Power Management and GPIO expander driver for "
+                  "MPC8349E-mITX-compatible MCU");
+MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
index 307d976c9b69b977c389e62abfbe43682b1d3e24..c171988a9f517d7009319674265c47a10859a8c3 100644 (file)
@@ -521,9 +521,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
                return PTR_ERR(i2c_dev);
 
        /* register this i2c device with the driver core */
-       i2c_dev->dev = device_create_drvdata(i2c_dev_class, &adap->dev,
-                                            MKDEV(I2C_MAJOR, adap->nr),
-                                            NULL, "i2c-%d", adap->nr);
+       i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
+                                    MKDEV(I2C_MAJOR, adap->nr), NULL,
+                                    "i2c-%d", adap->nr);
        if (IS_ERR(i2c_dev->dev)) {
                res = PTR_ERR(i2c_dev->dev);
                goto error;
index 6c6dd2facede2e33366ce4dcbb584edc4e3811f8..74a369a6116fc7fbeb7bea0c68c629ec4cfb1102 100644 (file)
@@ -4,7 +4,7 @@
 
 # Select HAVE_IDE if IDE is supported
 config HAVE_IDE
-       def_bool n
+       bool
 
 menuconfig IDE
        tristate "ATA/ATAPI/MFM/RLL support"
index f27baa5f140e903cff37678d6be157be55f4decd..19f8c7770a25d7449486b3df07b56cf536ee5b76 100644 (file)
@@ -657,8 +657,8 @@ static int ide_register_port(ide_hwif_t *hwif)
                goto out;
        }
 
-       hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev,
-                                             MKDEV(0, 0), hwif, hwif->name);
+       hwif->portdev = device_create(ide_port_class, &hwif->gendev,
+                                     MKDEV(0, 0), hwif, hwif->name);
        if (IS_ERR(hwif->portdev)) {
                ret = PTR_ERR(hwif->portdev);
                device_unregister(&hwif->gendev);
index 25ac60f532730a0d19edfdf923f660f7c8b4e0dc..d879c7797cde3a6ab961088f65ac17ca441f4120 100644 (file)
@@ -2420,12 +2420,11 @@ static int ide_tape_probe(ide_drive_t *drive)
 
        idetape_setup(drive, tape, minor);
 
-       device_create_drvdata(idetape_sysfs_class, &drive->gendev,
-                             MKDEV(IDETAPE_MAJOR, minor), NULL,
-                             "%s", tape->name);
-       device_create_drvdata(idetape_sysfs_class, &drive->gendev,
-                             MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
-                             "n%s", tape->name);
+       device_create(idetape_sysfs_class, &drive->gendev,
+                     MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name);
+       device_create(idetape_sysfs_class, &drive->gendev,
+                     MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
+                     "n%s", tape->name);
 
        g->fops = &idetape_block_ops;
        ide_register_region(g);
index 9f95337139e3144424aba9c2e452939563f24586..5e38a68b8af279b0f6ad5a1280ef74db312f5730 100644 (file)
@@ -84,7 +84,7 @@ static const u8 csr1212_key_id_type_map[0x30] = {
 
 
 #define quads_to_bytes(_q) ((_q) * sizeof(u32))
-#define bytes_to_quads(_b) (((_b) + sizeof(u32) - 1) / sizeof(u32))
+#define bytes_to_quads(_b) DIV_ROUND_UP(_b, sizeof(u32))
 
 static void free_keyval(struct csr1212_keyval *kv)
 {
index b6eb2cf25914479667439fa51e181fca1e986fbd..2f83543a9dfca95c797e42421055497fc1c6f2e0 100644 (file)
@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
                /* default SYT offset is 3 cycles */
                init->syt_offset = 3;
 
-       if ( (init->channel > 63) || (init->channel < 0) )
+       if (init->channel > 63)
                init->channel = 63;
 
        chan_mask = (u64)1 << init->channel;
@@ -2296,10 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host)
 
        ohci = (struct ti_ohci *)host->hostdata;
 
-       device_create_drvdata(hpsb_protocol_class, NULL,
-                             MKDEV(IEEE1394_MAJOR,
-                                   IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL,
-                             "dv1394-%d", id);
+       device_create(hpsb_protocol_class, NULL,
+                     MKDEV(IEEE1394_MAJOR,
+                           IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
+                     NULL, "dv1394-%d", id);
 
        dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
        dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
index b166b3575fa6d8904126e8a61ccaf604d5b9739f..20128692b3398be1c3a8556e78b593718894bdc1 100644 (file)
@@ -1361,7 +1361,7 @@ static unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
                hdr->ff.dgl = dgl;
                adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
        }
-       return (dg_size + adj_max_payload - 1) / adj_max_payload;
+       return DIV_ROUND_UP(dg_size, adj_max_payload);
 }
 
 static unsigned int ether1394_encapsulate(struct sk_buff *skb,
index 16240a7896509c024bacf59ff48bd8dd1c227d9d..2376b729e8765c5ca85bb7f1e0acf7201fe3b227 100644 (file)
@@ -154,9 +154,6 @@ struct host_info {
 
 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
 static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
-static void nodemgr_resume_ne(struct node_entry *ne);
-static void nodemgr_remove_ne(struct node_entry *ne);
-static struct node_entry *find_entry_by_guid(u64 guid);
 
 struct bus_type ieee1394_bus_type = {
        .name           = "ieee1394",
@@ -385,27 +382,6 @@ static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute
 static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver);
 
 
-static ssize_t fw_set_destroy_node(struct bus_type *bus, const char *buf, size_t count)
-{
-       struct node_entry *ne;
-       u64 guid = (u64)simple_strtoull(buf, NULL, 16);
-
-       ne = find_entry_by_guid(guid);
-
-       if (ne == NULL || !ne->in_limbo)
-               return -EINVAL;
-
-       nodemgr_remove_ne(ne);
-
-       return count;
-}
-static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
-{
-       return sprintf(buf, "You can destroy in_limbo nodes by writing their GUID to this file\n");
-}
-static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
-
-
 static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf,
                             size_t count)
 {
@@ -442,7 +418,6 @@ static BUS_ATTR(ignore_drivers, S_IWUSR | S_IRUGO, fw_get_ignore_drivers, fw_set
 
 
 struct bus_attribute *const fw_bus_attrs[] = {
-       &bus_attr_destroy_node,
        &bus_attr_rescan,
        &bus_attr_ignore_drivers,
        NULL
@@ -734,10 +709,10 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
 
 static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
 
-static int __match_ne(struct device *dev, void *data)
+static int match_ne(struct device *dev, void *data)
 {
        struct unit_directory *ud;
-       struct node_entry *ne = (struct node_entry *)data;
+       struct node_entry *ne = data;
 
        ud = container_of(dev, struct unit_directory, unit_dev);
        return ud->ne == ne;
@@ -754,8 +729,7 @@ static void nodemgr_remove_uds(struct node_entry *ne)
         */
        mutex_lock(&nodemgr_serialize_remove_uds);
        for (;;) {
-               dev = class_find_device(&nodemgr_ud_class, NULL, ne,
-                                       __match_ne);
+               dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne);
                if (!dev)
                        break;
                ud = container_of(dev, struct unit_directory, unit_dev);
@@ -785,7 +759,7 @@ static void nodemgr_remove_ne(struct node_entry *ne)
        put_device(dev);
 }
 
-static int __nodemgr_remove_host_dev(struct device *dev, void *data)
+static int remove_host_dev(struct device *dev, void *data)
 {
        if (dev->bus == &ieee1394_bus_type)
                nodemgr_remove_ne(container_of(dev, struct node_entry,
@@ -795,7 +769,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data)
 
 static void nodemgr_remove_host_dev(struct device *dev)
 {
-       WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev));
+       device_for_each_child(dev, NULL, remove_host_dev);
        sysfs_remove_link(&dev->kobj, "irm_id");
        sysfs_remove_link(&dev->kobj, "busmgr_id");
        sysfs_remove_link(&dev->kobj, "host_id");
@@ -830,11 +804,10 @@ static void nodemgr_update_bus_options(struct node_entry *ne)
 }
 
 
-static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr *csr,
-                                             struct host_info *hi, nodeid_t nodeid,
-                                             unsigned int generation)
+static struct node_entry *nodemgr_create_node(octlet_t guid,
+                               struct csr1212_csr *csr, struct hpsb_host *host,
+                               nodeid_t nodeid, unsigned int generation)
 {
-       struct hpsb_host *host = hi->host;
        struct node_entry *ne;
 
        ne = kzalloc(sizeof(*ne), GFP_KERNEL);
@@ -888,10 +861,10 @@ fail_alloc:
        return NULL;
 }
 
-static int __match_ne_guid(struct device *dev, void *data)
+static int match_ne_guid(struct device *dev, void *data)
 {
        struct node_entry *ne;
-       u64 *guid = (u64 *)data;
+       u64 *guid = data;
 
        ne = container_of(dev, struct node_entry, node_dev);
        return ne->guid == *guid;
@@ -902,8 +875,7 @@ static struct node_entry *find_entry_by_guid(u64 guid)
        struct device *dev;
        struct node_entry *ne;
 
-       dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
-                               __match_ne_guid);
+       dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid);
        if (!dev)
                return NULL;
        ne = container_of(dev, struct node_entry, node_dev);
@@ -912,21 +884,21 @@ static struct node_entry *find_entry_by_guid(u64 guid)
        return ne;
 }
 
-struct match_nodeid_param {
+struct match_nodeid_parameter {
        struct hpsb_host *host;
        nodeid_t nodeid;
 };
 
-static int __match_ne_nodeid(struct device *dev, void *data)
+static int match_ne_nodeid(struct device *dev, void *data)
 {
        int found = 0;
        struct node_entry *ne;
-       struct match_nodeid_param *param = (struct match_nodeid_param *)data;
+       struct match_nodeid_parameter *p = data;
 
        if (!dev)
                goto ret;
        ne = container_of(dev, struct node_entry, node_dev);
-       if (ne->host == param->host && ne->nodeid == param->nodeid)
+       if (ne->host == p->host && ne->nodeid == p->nodeid)
                found = 1;
 ret:
        return found;
@@ -937,13 +909,12 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
 {
        struct device *dev;
        struct node_entry *ne;
-       struct match_nodeid_param param;
+       struct match_nodeid_parameter p;
 
-       param.host = host;
-       param.nodeid = nodeid;
+       p.host = host;
+       p.nodeid = nodeid;
 
-       dev = class_find_device(&nodemgr_ne_class, NULL, &param,
-                               __match_ne_nodeid);
+       dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid);
        if (!dev)
                return NULL;
        ne = container_of(dev, struct node_entry, node_dev);
@@ -990,7 +961,7 @@ fail_devreg:
  * immediate unit directories looking for software_id and
  * software_version entries, in order to get driver autoloading working. */
 static struct unit_directory *nodemgr_process_unit_directory
-       (struct host_info *hi, struct node_entry *ne, struct csr1212_keyval *ud_kv,
+       (struct node_entry *ne, struct csr1212_keyval *ud_kv,
         unsigned int *id, struct unit_directory *parent)
 {
        struct unit_directory *ud;
@@ -1083,7 +1054,7 @@ static struct unit_directory *nodemgr_process_unit_directory
                                        nodemgr_register_device(ne, ud, &ne->device);
                                
                                /* process the child unit */
-                               ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud);
+                               ud_child = nodemgr_process_unit_directory(ne, kv, id, ud);
 
                                if (ud_child == NULL)
                                        break;
@@ -1137,7 +1108,7 @@ unit_directory_error:
 }
 
 
-static void nodemgr_process_root_directory(struct host_info *hi, struct node_entry *ne)
+static void nodemgr_process_root_directory(struct node_entry *ne)
 {
        unsigned int ud_id = 0;
        struct csr1212_dentry *dentry;
@@ -1157,7 +1128,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
                        break;
 
                case CSR1212_KV_ID_UNIT:
-                       nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL);
+                       nodemgr_process_unit_directory(ne, kv, &ud_id, NULL);
                        break;
 
                case CSR1212_KV_ID_DESCRIPTOR:
@@ -1273,8 +1244,7 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
  * the to take whatever actions required.
  */
 static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
-                               struct host_info *hi, nodeid_t nodeid,
-                               unsigned int generation)
+                               nodeid_t nodeid, unsigned int generation)
 {
        if (ne->nodeid != nodeid) {
                HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT,
@@ -1305,19 +1275,23 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
                csr1212_destroy_csr(csr);
        }
 
-       if (ne->in_limbo)
-               nodemgr_resume_ne(ne);
-
        /* Mark the node current */
        ne->generation = generation;
-}
 
+       if (ne->in_limbo) {
+               device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
+               ne->in_limbo = false;
 
+               HPSB_DEBUG("Node reactivated: "
+                          "ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
+                          NODE_BUS_ARGS(ne->host, ne->nodeid),
+                          (unsigned long long)ne->guid);
+       }
+}
 
-static void nodemgr_node_scan_one(struct host_info *hi,
+static void nodemgr_node_scan_one(struct hpsb_host *host,
                                  nodeid_t nodeid, int generation)
 {
-       struct hpsb_host *host = hi->host;
        struct node_entry *ne;
        octlet_t guid;
        struct csr1212_csr *csr;
@@ -1373,16 +1347,15 @@ static void nodemgr_node_scan_one(struct host_info *hi,
        }
 
        if (!ne)
-               nodemgr_create_node(guid, csr, hi, nodeid, generation);
+               nodemgr_create_node(guid, csr, host, nodeid, generation);
        else
-               nodemgr_update_node(ne, csr, hi, nodeid, generation);
+               nodemgr_update_node(ne, csr, nodeid, generation);
 }
 
 
-static void nodemgr_node_scan(struct host_info *hi, int generation)
+static void nodemgr_node_scan(struct hpsb_host *host, int generation)
 {
        int count;
-       struct hpsb_host *host = hi->host;
        struct selfid *sid = (struct selfid *)host->topology_map;
        nodeid_t nodeid = LOCAL_BUS;
 
@@ -1395,89 +1368,26 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
                        nodeid++;
                        continue;
                }
-               nodemgr_node_scan_one(hi, nodeid++, generation);
-       }
-}
-
-static int __nodemgr_driver_suspend(struct device *dev, void *data)
-{
-       struct unit_directory *ud;
-       struct device_driver *drv;
-       struct node_entry *ne = (struct node_entry *)data;
-       int error;
-
-       ud = container_of(dev, struct unit_directory, unit_dev);
-       if (ud->ne == ne) {
-               drv = get_driver(ud->device.driver);
-               if (drv) {
-                       error = 1; /* release if suspend is not implemented */
-                       if (drv->suspend) {
-                               down(&ud->device.sem);
-                               error = drv->suspend(&ud->device, PMSG_SUSPEND);
-                               up(&ud->device.sem);
-                       }
-                       if (error)
-                               device_release_driver(&ud->device);
-                       put_driver(drv);
-               }
-       }
-
-       return 0;
-}
-
-static int __nodemgr_driver_resume(struct device *dev, void *data)
-{
-       struct unit_directory *ud;
-       struct device_driver *drv;
-       struct node_entry *ne = (struct node_entry *)data;
-
-       ud = container_of(dev, struct unit_directory, unit_dev);
-       if (ud->ne == ne) {
-               drv = get_driver(ud->device.driver);
-               if (drv) {
-                       if (drv->resume) {
-                               down(&ud->device.sem);
-                               drv->resume(&ud->device);
-                               up(&ud->device.sem);
-                       }
-                       put_driver(drv);
-               }
+               nodemgr_node_scan_one(host, nodeid++, generation);
        }
-
-       return 0;
 }
 
-static void nodemgr_suspend_ne(struct node_entry *ne)
+static void nodemgr_pause_ne(struct node_entry *ne)
 {
-       HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
+       HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
                   NODE_BUS_ARGS(ne->host, ne->nodeid),
                   (unsigned long long)ne->guid);
 
-       ne->in_limbo = 1;
+       ne->in_limbo = true;
        WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
-
-       class_for_each_device(&nodemgr_ud_class, NULL, ne,
-                             __nodemgr_driver_suspend);
-}
-
-
-static void nodemgr_resume_ne(struct node_entry *ne)
-{
-       ne->in_limbo = 0;
-       device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
-
-       class_for_each_device(&nodemgr_ud_class, NULL, ne,
-                             __nodemgr_driver_resume);
-       HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
-                  NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 }
 
-static int __nodemgr_update_pdrv(struct device *dev, void *data)
+static int update_pdrv(struct device *dev, void *data)
 {
        struct unit_directory *ud;
        struct device_driver *drv;
        struct hpsb_protocol_driver *pdrv;
-       struct node_entry *ne = (struct node_entry *)data;
+       struct node_entry *ne = data;
        int error;
 
        ud = container_of(dev, struct unit_directory, unit_dev);
@@ -1503,11 +1413,9 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data)
 
 static void nodemgr_update_pdrv(struct node_entry *ne)
 {
-       class_for_each_device(&nodemgr_ud_class, NULL, ne,
-                             __nodemgr_update_pdrv);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv);
 }
 
-
 /* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3.  This
  * seems like an optional service but in the end it is practically mandatory
  * as a consequence of these clauses.
@@ -1535,11 +1443,12 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
 }
 
 
-static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
+static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne,
+                            int generation)
 {
        struct device *dev;
 
-       if (ne->host != hi->host || ne->in_limbo)
+       if (ne->host != host || ne->in_limbo)
                return;
 
        dev = get_device(&ne->device);
@@ -1554,40 +1463,40 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
         * down to the drivers. Otherwise, this is a dead node and we
         * suspend it. */
        if (ne->needs_probe)
-               nodemgr_process_root_directory(hi, ne);
+               nodemgr_process_root_directory(ne);
        else if (ne->generation == generation)
                nodemgr_update_pdrv(ne);
        else
-               nodemgr_suspend_ne(ne);
+               nodemgr_pause_ne(ne);
 
        put_device(dev);
 }
 
-struct probe_param {
-       struct host_info *hi;
+struct node_probe_parameter {
+       struct hpsb_host *host;
        int generation;
        bool probe_now;
 };
 
 static int node_probe(struct device *dev, void *data)
 {
-       struct probe_param *p = data;
+       struct node_probe_parameter *p = data;
        struct node_entry *ne;
 
-       if (p->generation != get_hpsb_generation(p->hi->host))
+       if (p->generation != get_hpsb_generation(p->host))
                return -EAGAIN;
 
        ne = container_of(dev, struct node_entry, node_dev);
        if (ne->needs_probe == p->probe_now)
-               nodemgr_probe_ne(p->hi, ne, p->generation);
+               nodemgr_probe_ne(p->host, ne, p->generation);
        return 0;
 }
 
-static void nodemgr_node_probe(struct host_info *hi, int generation)
+static int nodemgr_node_probe(struct hpsb_host *host, int generation)
 {
-       struct probe_param p;
+       struct node_probe_parameter p;
 
-       p.hi = hi;
+       p.host = host;
        p.generation = generation;
        /*
         * Do some processing of the nodes we've probed. This pulls them
@@ -1604,11 +1513,11 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         */
        p.probe_now = false;
        if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
-               return;
+               return 0;
 
        p.probe_now = true;
        if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
-               return;
+               return 0;
        /*
         * Now let's tell the bus to rescan our devices. This may seem
         * like overhead, but the driver-model core will only scan a
@@ -1620,6 +1529,27 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         */
        if (bus_rescan_devices(&ieee1394_bus_type) != 0)
                HPSB_DEBUG("bus_rescan_devices had an error");
+
+       return 1;
+}
+
+static int remove_nodes_in_limbo(struct device *dev, void *data)
+{
+       struct node_entry *ne;
+
+       if (dev->bus != &ieee1394_bus_type)
+               return 0;
+
+       ne = container_of(dev, struct node_entry, device);
+       if (ne->in_limbo)
+               nodemgr_remove_ne(ne);
+
+       return 0;
+}
+
+static void nodemgr_remove_nodes_in_limbo(struct hpsb_host *host)
+{
+       device_for_each_child(&host->device, NULL, remove_nodes_in_limbo);
 }
 
 static int nodemgr_send_resume_packet(struct hpsb_host *host)
@@ -1730,10 +1660,9 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles)
        return 1;
 }
 
-static int nodemgr_host_thread(void *__hi)
+static int nodemgr_host_thread(void *data)
 {
-       struct host_info *hi = (struct host_info *)__hi;
-       struct hpsb_host *host = hi->host;
+       struct hpsb_host *host = data;
        unsigned int g, generation = 0;
        int i, reset_cycles = 0;
 
@@ -1787,36 +1716,48 @@ static int nodemgr_host_thread(void *__hi)
                 * entries. This does not do the sysfs stuff, since that
                 * would trigger uevents and such, which is a bad idea at
                 * this point. */
-               nodemgr_node_scan(hi, generation);
+               nodemgr_node_scan(host, generation);
 
                /* This actually does the full probe, with sysfs
                 * registration. */
-               nodemgr_node_probe(hi, generation);
+               if (!nodemgr_node_probe(host, generation))
+                       continue;
 
                /* Update some of our sysfs symlinks */
                nodemgr_update_host_dev_links(host);
+
+               /* Sleep 3 seconds */
+               for (i = 3000/200; i; i--) {
+                       msleep_interruptible(200);
+                       if (kthread_should_stop())
+                               goto exit;
+
+                       if (generation != get_hpsb_generation(host))
+                               break;
+               }
+               /* Remove nodes which are gone, unless a bus reset happened */
+               if (!i)
+                       nodemgr_remove_nodes_in_limbo(host);
        }
 exit:
        HPSB_VERBOSE("NodeMgr: Exiting thread");
        return 0;
 }
 
-struct host_iter_param {
+struct per_host_parameter {
        void *data;
        int (*cb)(struct hpsb_host *, void *);
 };
 
-static int __nodemgr_for_each_host(struct device *dev, void *data)
+static int per_host(struct device *dev, void *data)
 {
        struct hpsb_host *host;
-       struct host_iter_param *hip = (struct host_iter_param *)data;
-       int error = 0;
+       struct per_host_parameter *p = data;
 
        host = container_of(dev, struct hpsb_host, host_dev);
-       error = hip->cb(host, hip->data);
-
-       return error;
+       return p->cb(host, p->data);
 }
+
 /**
  * nodemgr_for_each_host - call a function for each IEEE 1394 host
  * @data: an address to supply to the callback
@@ -1831,15 +1772,11 @@ static int __nodemgr_for_each_host(struct device *dev, void *data)
  */
 int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
 {
-       struct host_iter_param hip;
-       int error;
-
-       hip.cb = cb;
-       hip.data = data;
-       error = class_for_each_device(&hpsb_host_class, NULL, &hip,
-                                     __nodemgr_for_each_host);
+       struct per_host_parameter p;
 
-       return error;
+       p.cb = cb;
+       p.data = data;
+       return class_for_each_device(&hpsb_host_class, NULL, &p, per_host);
 }
 
 /* The following two convenience functions use a struct node_entry
@@ -1893,7 +1830,7 @@ static void nodemgr_add_host(struct hpsb_host *host)
                return;
        }
        hi->host = host;
-       hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d",
+       hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d",
                                 host->id);
        if (IS_ERR(hi->thread)) {
                HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
index 6eb26465a84ca44029c4d43cc3ba17ba1eb1c378..4f287a3561ba9943b8ecc9c8e33963da15fba9b3 100644 (file)
@@ -110,7 +110,7 @@ struct node_entry {
        struct device node_dev;
 
        /* Means this node is not attached anymore */
-       int in_limbo;
+       bool in_limbo;
 
        struct csr1212_csr *csr;
 };
index a06aaad5b448da6072a0c4469b60cfa64eafa1e3..7a225a4059870b17a43db380f9aa17b784f8cdd0 100644 (file)
@@ -22,6 +22,7 @@ enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0,
 struct file_info {
         struct list_head list;
 
+       struct mutex state_mutex;
         enum { opened, initialized, connected } state;
         unsigned int protocol_version;
 
index 6fa9e4a21840b5f0cad2ce28b3754b293913e8fc..9f19ac492106a8107a0d9fc2f2af66d92908dfe0 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
@@ -2267,6 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
                return -EFAULT;
        }
 
+       mutex_lock(&fi->state_mutex);
+
        switch (fi->state) {
        case opened:
                retval = state_opened(fi, req);
@@ -2281,6 +2284,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
                break;
        }
 
+       mutex_unlock(&fi->state_mutex);
+
        if (retval < 0) {
                free_pending_request(req);
        } else {
@@ -2541,109 +2546,120 @@ static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
 static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
 {
        struct file_info *fi = file->private_data;
+       int ret;
+
+       mutex_lock(&fi->state_mutex);
 
        if (fi->iso_state == RAW1394_ISO_INACTIVE)
-               return -EINVAL;
+               ret = -EINVAL;
+       else
+               ret = dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
+
+       mutex_unlock(&fi->state_mutex);
 
-       return dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
+       return ret;
 }
 
-/* ioctl is only used for rawiso operations */
-static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
-                                                       unsigned long arg)
+static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd,
+                                  void __user *argp)
+{
+       switch (cmd) {
+       case RAW1394_IOC_ISO_XMIT_INIT:
+               return raw1394_iso_xmit_init(fi, argp);
+       case RAW1394_IOC_ISO_RECV_INIT:
+               return raw1394_iso_recv_init(fi, argp);
+       default:
+               return -EINVAL;
+       }
+}
+
+static long raw1394_ioctl_recv(struct file_info *fi, unsigned int cmd,
+                              unsigned long arg)
 {
-       struct file_info *fi = file->private_data;
        void __user *argp = (void __user *)arg;
 
-       switch (fi->iso_state) {
-       case RAW1394_ISO_INACTIVE:
-               switch (cmd) {
-               case RAW1394_IOC_ISO_XMIT_INIT:
-                       return raw1394_iso_xmit_init(fi, argp);
-               case RAW1394_IOC_ISO_RECV_INIT:
-                       return raw1394_iso_recv_init(fi, argp);
-               default:
-                       break;
+       switch (cmd) {
+       case RAW1394_IOC_ISO_RECV_START:{
+                       int args[3];
+
+                       if (copy_from_user(&args[0], argp, sizeof(args)))
+                               return -EFAULT;
+                       return hpsb_iso_recv_start(fi->iso_handle,
+                                                  args[0], args[1], args[2]);
                }
-               break;
-       case RAW1394_ISO_RECV:
-               switch (cmd) {
-               case RAW1394_IOC_ISO_RECV_START:{
-                               /* copy args from user-space */
-                               int args[3];
-                               if (copy_from_user
-                                   (&args[0], argp, sizeof(args)))
-                                       return -EFAULT;
-                               return hpsb_iso_recv_start(fi->iso_handle,
-                                                          args[0], args[1],
-                                                          args[2]);
-                       }
-               case RAW1394_IOC_ISO_XMIT_RECV_STOP:
-                       hpsb_iso_stop(fi->iso_handle);
-                       return 0;
-               case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
-                       return hpsb_iso_recv_listen_channel(fi->iso_handle,
-                                                           arg);
-               case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
-                       return hpsb_iso_recv_unlisten_channel(fi->iso_handle,
-                                                             arg);
-               case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
-                               /* copy the u64 from user-space */
-                               u64 mask;
-                               if (copy_from_user(&mask, argp, sizeof(mask)))
-                                       return -EFAULT;
-                               return hpsb_iso_recv_set_channel_mask(fi->
-                                                                     iso_handle,
-                                                                     mask);
-                       }
-               case RAW1394_IOC_ISO_GET_STATUS:
-                       return raw1394_iso_get_status(fi, argp);
-               case RAW1394_IOC_ISO_RECV_PACKETS:
-                       return raw1394_iso_recv_packets(fi, argp);
-               case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
-                       return hpsb_iso_recv_release_packets(fi->iso_handle,
-                                                            arg);
-               case RAW1394_IOC_ISO_RECV_FLUSH:
-                       return hpsb_iso_recv_flush(fi->iso_handle);
-               case RAW1394_IOC_ISO_SHUTDOWN:
-                       raw1394_iso_shutdown(fi);
-                       return 0;
-               case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
-                       queue_rawiso_event(fi);
-                       return 0;
+       case RAW1394_IOC_ISO_XMIT_RECV_STOP:
+               hpsb_iso_stop(fi->iso_handle);
+               return 0;
+       case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
+               return hpsb_iso_recv_listen_channel(fi->iso_handle, arg);
+       case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
+               return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg);
+       case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
+                       u64 mask;
+
+                       if (copy_from_user(&mask, argp, sizeof(mask)))
+                               return -EFAULT;
+                       return hpsb_iso_recv_set_channel_mask(fi->iso_handle,
+                                                             mask);
                }
-               break;
-       case RAW1394_ISO_XMIT:
-               switch (cmd) {
-               case RAW1394_IOC_ISO_XMIT_START:{
-                               /* copy two ints from user-space */
-                               int args[2];
-                               if (copy_from_user
-                                   (&args[0], argp, sizeof(args)))
-                                       return -EFAULT;
-                               return hpsb_iso_xmit_start(fi->iso_handle,
-                                                          args[0], args[1]);
-                       }
-               case RAW1394_IOC_ISO_XMIT_SYNC:
-                       return hpsb_iso_xmit_sync(fi->iso_handle);
-               case RAW1394_IOC_ISO_XMIT_RECV_STOP:
-                       hpsb_iso_stop(fi->iso_handle);
-                       return 0;
-               case RAW1394_IOC_ISO_GET_STATUS:
-                       return raw1394_iso_get_status(fi, argp);
-               case RAW1394_IOC_ISO_XMIT_PACKETS:
-                       return raw1394_iso_send_packets(fi, argp);
-               case RAW1394_IOC_ISO_SHUTDOWN:
-                       raw1394_iso_shutdown(fi);
-                       return 0;
-               case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
-                       queue_rawiso_event(fi);
-                       return 0;
+       case RAW1394_IOC_ISO_GET_STATUS:
+               return raw1394_iso_get_status(fi, argp);
+       case RAW1394_IOC_ISO_RECV_PACKETS:
+               return raw1394_iso_recv_packets(fi, argp);
+       case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
+               return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
+       case RAW1394_IOC_ISO_RECV_FLUSH:
+               return hpsb_iso_recv_flush(fi->iso_handle);
+       case RAW1394_IOC_ISO_SHUTDOWN:
+               raw1394_iso_shutdown(fi);
+               return 0;
+       case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
+               queue_rawiso_event(fi);
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static long raw1394_ioctl_xmit(struct file_info *fi, unsigned int cmd,
+                              void __user *argp)
+{
+       switch (cmd) {
+       case RAW1394_IOC_ISO_XMIT_START:{
+                       int args[2];
+
+                       if (copy_from_user(&args[0], argp, sizeof(args)))
+                               return -EFAULT;
+                       return hpsb_iso_xmit_start(fi->iso_handle,
+                                                  args[0], args[1]);
                }
-               break;
+       case RAW1394_IOC_ISO_XMIT_SYNC:
+               return hpsb_iso_xmit_sync(fi->iso_handle);
+       case RAW1394_IOC_ISO_XMIT_RECV_STOP:
+               hpsb_iso_stop(fi->iso_handle);
+               return 0;
+       case RAW1394_IOC_ISO_GET_STATUS:
+               return raw1394_iso_get_status(fi, argp);
+       case RAW1394_IOC_ISO_XMIT_PACKETS:
+               return raw1394_iso_send_packets(fi, argp);
+       case RAW1394_IOC_ISO_SHUTDOWN:
+               raw1394_iso_shutdown(fi);
+               return 0;
+       case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
+               queue_rawiso_event(fi);
+               return 0;
        default:
-               break;
+               return -EINVAL;
        }
+}
+
+/* ioctl is only used for rawiso operations */
+static long raw1394_ioctl(struct file *file, unsigned int cmd,
+                         unsigned long arg)
+{
+       struct file_info *fi = file->private_data;
+       void __user *argp = (void __user *)arg;
+       long ret;
 
        /* state-independent commands */
        switch(cmd) {
@@ -2653,16 +2669,25 @@ static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
                break;
        }
 
-       return -EINVAL;
-}
+       mutex_lock(&fi->state_mutex);
+
+       switch (fi->iso_state) {
+       case RAW1394_ISO_INACTIVE:
+               ret = raw1394_ioctl_inactive(fi, cmd, argp);
+               break;
+       case RAW1394_ISO_RECV:
+               ret = raw1394_ioctl_recv(fi, cmd, arg);
+               break;
+       case RAW1394_ISO_XMIT:
+               ret = raw1394_ioctl_xmit(fi, cmd, argp);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       mutex_unlock(&fi->state_mutex);
 
-static long raw1394_ioctl(struct file *file, unsigned int cmd,
-                                                       unsigned long arg)
-{
-       long ret;
-       lock_kernel();
-       ret = do_raw1394_ioctl(file, cmd, arg);
-       unlock_kernel();
        return ret;
 }
 
@@ -2700,7 +2725,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
            !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
                infos = compat_ptr(infos32);
                if (!copy_to_user(&dst->infos, &infos, sizeof infos))
-                       err = do_raw1394_ioctl(file, cmd, (unsigned long)dst);
+                       err = raw1394_ioctl(file, cmd, (unsigned long)dst);
        }
        return err;
 }
@@ -2724,7 +2749,6 @@ static long raw1394_compat_ioctl(struct file *file,
        void __user *argp = (void __user *)arg;
        long err;
 
-       lock_kernel();
        switch (cmd) {
        /* These requests have same format as long as 'int' has same size. */
        case RAW1394_IOC_ISO_RECV_INIT:
@@ -2741,7 +2765,7 @@ static long raw1394_compat_ioctl(struct file *file,
        case RAW1394_IOC_ISO_GET_STATUS:
        case RAW1394_IOC_ISO_SHUTDOWN:
        case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
-               err = do_raw1394_ioctl(file, cmd, arg);
+               err = raw1394_ioctl(file, cmd, arg);
                break;
        /* These request have different format. */
        case RAW1394_IOC_ISO_RECV_PACKETS32:
@@ -2757,7 +2781,6 @@ static long raw1394_compat_ioctl(struct file *file,
                err = -EINVAL;
                break;
        }
-       unlock_kernel();
 
        return err;
 }
@@ -2791,6 +2814,7 @@ static int raw1394_open(struct inode *inode, struct file *file)
        fi->notification = (u8) RAW1394_NOTIFY_ON;      /* busreset notification */
 
        INIT_LIST_HEAD(&fi->list);
+       mutex_init(&fi->state_mutex);
        fi->state = opened;
        INIT_LIST_HEAD(&fi->req_pending);
        INIT_LIST_HEAD(&fi->req_complete);
@@ -3010,10 +3034,10 @@ static int __init init_raw1394(void)
        hpsb_register_highlevel(&raw1394_highlevel);
 
        if (IS_ERR
-           (device_create_drvdata(
-             hpsb_protocol_class, NULL,
-             MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
-             NULL, RAW1394_DEVICE_NAME))) {
+           (device_create(hpsb_protocol_class, NULL,
+                          MKDEV(IEEE1394_MAJOR,
+                                IEEE1394_MINOR_BLOCK_RAW1394 * 16),
+                          NULL, RAW1394_DEVICE_NAME))) {
                ret = -EFAULT;
                goto out_unreg;
        }
index 1d6ad34355372f1c492d984e1c8b56f625d0acf6..c52f6e6e8af2a8bacac026e4f9974652ee794661 100644 (file)
@@ -526,26 +526,41 @@ static void sbp2util_write_doorbell(struct work_struct *work)
 
 static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu)
 {
-       struct sbp2_fwhost_info *hi = lu->hi;
        struct sbp2_command_info *cmd;
+       struct device *dmadev = lu->hi->host->device.parent;
        int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS;
 
        for (i = 0; i < orbs; i++) {
                cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
                if (!cmd)
-                       return -ENOMEM;
-               cmd->command_orb_dma = dma_map_single(hi->host->device.parent,
-                                               &cmd->command_orb,
-                                               sizeof(struct sbp2_command_orb),
-                                               DMA_TO_DEVICE);
-               cmd->sge_dma = dma_map_single(hi->host->device.parent,
-                                       &cmd->scatter_gather_element,
-                                       sizeof(cmd->scatter_gather_element),
-                                       DMA_TO_DEVICE);
+                       goto failed_alloc;
+
+               cmd->command_orb_dma =
+                   dma_map_single(dmadev, &cmd->command_orb,
+                                  sizeof(struct sbp2_command_orb),
+                                  DMA_TO_DEVICE);
+               if (dma_mapping_error(dmadev, cmd->command_orb_dma))
+                       goto failed_orb;
+
+               cmd->sge_dma =
+                   dma_map_single(dmadev, &cmd->scatter_gather_element,
+                                  sizeof(cmd->scatter_gather_element),
+                                  DMA_TO_DEVICE);
+               if (dma_mapping_error(dmadev, cmd->sge_dma))
+                       goto failed_sge;
+
                INIT_LIST_HEAD(&cmd->list);
                list_add_tail(&cmd->list, &lu->cmd_orb_completed);
        }
        return 0;
+
+failed_sge:
+       dma_unmap_single(dmadev, cmd->command_orb_dma,
+                        sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
+failed_orb:
+       kfree(cmd);
+failed_alloc:
+       return -ENOMEM;
 }
 
 static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu,
@@ -641,24 +656,11 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
 static void sbp2util_mark_command_completed(struct sbp2_lu *lu,
                                            struct sbp2_command_info *cmd)
 {
-       struct hpsb_host *host = lu->ud->ne->host;
-
-       if (cmd->cmd_dma) {
-               if (cmd->dma_type == CMD_DMA_SINGLE)
-                       dma_unmap_single(host->device.parent, cmd->cmd_dma,
-                                        cmd->dma_size, cmd->dma_dir);
-               else if (cmd->dma_type == CMD_DMA_PAGE)
-                       dma_unmap_page(host->device.parent, cmd->cmd_dma,
-                                      cmd->dma_size, cmd->dma_dir);
-               /* XXX: Check for CMD_DMA_NONE bug */
-               cmd->dma_type = CMD_DMA_NONE;
-               cmd->cmd_dma = 0;
-       }
-       if (cmd->sge_buffer) {
-               dma_unmap_sg(host->device.parent, cmd->sge_buffer,
-                            cmd->dma_size, cmd->dma_dir);
-               cmd->sge_buffer = NULL;
-       }
+       if (scsi_sg_count(cmd->Current_SCpnt))
+               dma_unmap_sg(lu->ud->ne->host->device.parent,
+                            scsi_sglist(cmd->Current_SCpnt),
+                            scsi_sg_count(cmd->Current_SCpnt),
+                            cmd->Current_SCpnt->sc_data_direction);
        list_move_tail(&cmd->list, &lu->cmd_orb_completed);
 }
 
@@ -823,6 +825,10 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
 #endif
        }
 
+       if (dma_get_max_seg_size(hi->host->device.parent) > SBP2_MAX_SEG_SIZE)
+               BUG_ON(dma_set_max_seg_size(hi->host->device.parent,
+                                           SBP2_MAX_SEG_SIZE));
+
        /* Prevent unloading of the 1394 host */
        if (!try_module_get(hi->host->driver->owner)) {
                SBP2_ERR("failed to get a reference on 1394 host driver");
@@ -1494,84 +1500,65 @@ static int sbp2_agent_reset(struct sbp2_lu *lu, int wait)
        return 0;
 }
 
-static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
-                                    struct sbp2_fwhost_info *hi,
-                                    struct sbp2_command_info *cmd,
-                                    unsigned int scsi_use_sg,
-                                    struct scatterlist *sg,
-                                    u32 orb_direction,
-                                    enum dma_data_direction dma_dir)
+static int sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+                                   struct sbp2_fwhost_info *hi,
+                                   struct sbp2_command_info *cmd,
+                                   unsigned int sg_count,
+                                   struct scatterlist *sg,
+                                   u32 orb_direction,
+                                   enum dma_data_direction dma_dir)
 {
-       cmd->dma_dir = dma_dir;
+       struct device *dmadev = hi->host->device.parent;
+       struct sbp2_unrestricted_page_table *pt;
+       int i, n;
+
+       n = dma_map_sg(dmadev, sg, sg_count, dma_dir);
+       if (n == 0)
+               return -ENOMEM;
+
        orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
        orb->misc |= ORB_SET_DIRECTION(orb_direction);
 
        /* special case if only one element (and less than 64KB in size) */
-       if (scsi_use_sg == 1 && sg->length <= SBP2_MAX_SG_ELEMENT_LENGTH) {
-
-               cmd->dma_size = sg->length;
-               cmd->dma_type = CMD_DMA_PAGE;
-               cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-                                           sg_page(sg), sg->offset,
-                                           cmd->dma_size, cmd->dma_dir);
-
-               orb->data_descriptor_lo = cmd->cmd_dma;
-               orb->misc |= ORB_SET_DATA_SIZE(cmd->dma_size);
-
+       if (n == 1) {
+               orb->misc |= ORB_SET_DATA_SIZE(sg_dma_len(sg));
+               orb->data_descriptor_lo = sg_dma_address(sg);
        } else {
-               struct sbp2_unrestricted_page_table *sg_element =
-                                               &cmd->scatter_gather_element[0];
-               u32 sg_count, sg_len;
-               dma_addr_t sg_addr;
-               int i, count = dma_map_sg(hi->host->device.parent, sg,
-                                         scsi_use_sg, dma_dir);
-
-               cmd->dma_size = scsi_use_sg;
-               cmd->sge_buffer = sg;
-
-               /* use page tables (s/g) */
-               orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-               orb->data_descriptor_lo = cmd->sge_dma;
+               pt = &cmd->scatter_gather_element[0];
 
-               /* loop through and fill out our SBP-2 page tables
-                * (and split up anything too large) */
-               for (i = 0, sg_count = 0; i < count; i++, sg = sg_next(sg)) {
-                       sg_len = sg_dma_len(sg);
-                       sg_addr = sg_dma_address(sg);
-                       while (sg_len) {
-                               sg_element[sg_count].segment_base_lo = sg_addr;
-                               if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
-                                       sg_element[sg_count].length_segment_base_hi =
-                                               PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
-                                       sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
-                                       sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
-                               } else {
-                                       sg_element[sg_count].length_segment_base_hi =
-                                               PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
-                                       sg_len = 0;
-                               }
-                               sg_count++;
-                       }
+               dma_sync_single_for_cpu(dmadev, cmd->sge_dma,
+                                       sizeof(cmd->scatter_gather_element),
+                                       DMA_TO_DEVICE);
+
+               for_each_sg(sg, sg, n, i) {
+                       pt[i].high = cpu_to_be32(sg_dma_len(sg) << 16);
+                       pt[i].low = cpu_to_be32(sg_dma_address(sg));
                }
 
-               orb->misc |= ORB_SET_DATA_SIZE(sg_count);
+               orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1) |
+                            ORB_SET_DATA_SIZE(n);
+               orb->data_descriptor_lo = cmd->sge_dma;
 
-               sbp2util_cpu_to_be32_buffer(sg_element,
-                               (sizeof(struct sbp2_unrestricted_page_table)) *
-                               sg_count);
+               dma_sync_single_for_device(dmadev, cmd->sge_dma,
+                                          sizeof(cmd->scatter_gather_element),
+                                          DMA_TO_DEVICE);
        }
+       return 0;
 }
 
-static void sbp2_create_command_orb(struct sbp2_lu *lu,
-                                   struct sbp2_command_info *cmd,
-                                   struct scsi_cmnd *SCpnt)
+static int sbp2_create_command_orb(struct sbp2_lu *lu,
+                                  struct sbp2_command_info *cmd,
+                                  struct scsi_cmnd *SCpnt)
 {
-       struct sbp2_fwhost_info *hi = lu->hi;
+       struct device *dmadev = lu->hi->host->device.parent;
        struct sbp2_command_orb *orb = &cmd->command_orb;
-       u32 orb_direction;
        unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt);
        enum dma_data_direction dma_dir = SCpnt->sc_data_direction;
+       u32 orb_direction;
+       int ret;
 
+       dma_sync_single_for_cpu(dmadev, cmd->command_orb_dma,
+                               sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
        /*
         * Set-up our command ORB.
         *
@@ -1602,15 +1589,21 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
                orb->data_descriptor_hi = 0x0;
                orb->data_descriptor_lo = 0x0;
                orb->misc |= ORB_SET_DIRECTION(1);
-       } else
-               sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt),
-                                        scsi_sglist(SCpnt),
-                                        orb_direction, dma_dir);
-
+               ret = 0;
+       } else {
+               ret = sbp2_prep_command_orb_sg(orb, lu->hi, cmd,
+                                              scsi_sg_count(SCpnt),
+                                              scsi_sglist(SCpnt),
+                                              orb_direction, dma_dir);
+       }
        sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb));
 
        memset(orb->cdb, 0, sizeof(orb->cdb));
        memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+       dma_sync_single_for_device(dmadev, cmd->command_orb_dma,
+                       sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
+       return ret;
 }
 
 static void sbp2_link_orb_command(struct sbp2_lu *lu,
@@ -1624,14 +1617,6 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu,
        size_t length;
        unsigned long flags;
 
-       dma_sync_single_for_device(hi->host->device.parent,
-                                  cmd->command_orb_dma,
-                                  sizeof(struct sbp2_command_orb),
-                                  DMA_TO_DEVICE);
-       dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma,
-                                  sizeof(cmd->scatter_gather_element),
-                                  DMA_TO_DEVICE);
-
        /* check to see if there are any previous orbs to use */
        spin_lock_irqsave(&lu->cmd_orb_lock, flags);
        last_orb = lu->last_orb;
@@ -1699,9 +1684,10 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
        if (!cmd)
                return -EIO;
 
-       sbp2_create_command_orb(lu, cmd, SCpnt);
-       sbp2_link_orb_command(lu, cmd);
+       if (sbp2_create_command_orb(lu, cmd, SCpnt))
+               return -ENOMEM;
 
+       sbp2_link_orb_command(lu, cmd);
        return 0;
 }
 
@@ -1789,13 +1775,6 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
        else
                cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo);
        if (cmd) {
-               dma_sync_single_for_cpu(hi->host->device.parent,
-                                       cmd->command_orb_dma,
-                                       sizeof(struct sbp2_command_orb),
-                                       DMA_TO_DEVICE);
-               dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
-                                       sizeof(cmd->scatter_gather_element),
-                                       DMA_TO_DEVICE);
                /* Grab SCSI command pointers and check status. */
                /*
                 * FIXME: If the src field in the status is 1, the ORB DMA must
@@ -1912,7 +1891,6 @@ done:
 
 static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
 {
-       struct sbp2_fwhost_info *hi = lu->hi;
        struct list_head *lh;
        struct sbp2_command_info *cmd;
        unsigned long flags;
@@ -1921,13 +1899,6 @@ static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
        while (!list_empty(&lu->cmd_orb_inuse)) {
                lh = lu->cmd_orb_inuse.next;
                cmd = list_entry(lh, struct sbp2_command_info, list);
-               dma_sync_single_for_cpu(hi->host->device.parent,
-                                       cmd->command_orb_dma,
-                                       sizeof(struct sbp2_command_orb),
-                                       DMA_TO_DEVICE);
-               dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
-                                       sizeof(cmd->scatter_gather_element),
-                                       DMA_TO_DEVICE);
                sbp2util_mark_command_completed(lu, cmd);
                if (cmd->Current_SCpnt) {
                        cmd->Current_SCpnt->result = status << 16;
@@ -2033,6 +2004,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
                sdev->start_stop_pwr_cond = 1;
        if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
                blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+
+       blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
        return 0;
 }
 
@@ -2049,7 +2022,6 @@ static void sbp2scsi_slave_destroy(struct scsi_device *sdev)
 static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
 {
        struct sbp2_lu *lu = (struct sbp2_lu *)SCpnt->device->host->hostdata[0];
-       struct sbp2_fwhost_info *hi = lu->hi;
        struct sbp2_command_info *cmd;
        unsigned long flags;
 
@@ -2063,14 +2035,6 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
                spin_lock_irqsave(&lu->cmd_orb_lock, flags);
                cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt);
                if (cmd) {
-                       dma_sync_single_for_cpu(hi->host->device.parent,
-                                       cmd->command_orb_dma,
-                                       sizeof(struct sbp2_command_orb),
-                                       DMA_TO_DEVICE);
-                       dma_sync_single_for_cpu(hi->host->device.parent,
-                                       cmd->sge_dma,
-                                       sizeof(cmd->scatter_gather_element),
-                                       DMA_TO_DEVICE);
                        sbp2util_mark_command_completed(lu, cmd);
                        if (cmd->Current_SCpnt) {
                                cmd->Current_SCpnt->result = DID_ABORT << 16;
index 875428bc8d2995fc475b332ca596552d1ebbabfa..c5036f1cc5b0d674155ea2a89087e9ba5e981eb5 100644 (file)
@@ -139,13 +139,10 @@ struct sbp2_logout_orb {
        u32 status_fifo_lo;
 } __attribute__((packed));
 
-#define PAGE_TABLE_SET_SEGMENT_BASE_HI(v)      ((v) & 0xffff)
-#define PAGE_TABLE_SET_SEGMENT_LENGTH(v)       (((v) & 0xffff) << 16)
-
 struct sbp2_unrestricted_page_table {
-       u32 length_segment_base_hi;
-       u32 segment_base_lo;
-} __attribute__((packed));
+       __be32 high;
+       __be32 low;
+};
 
 #define RESP_STATUS_REQUEST_COMPLETE           0x0
 #define RESP_STATUS_TRANSPORT_FAILURE          0x1
@@ -216,15 +213,18 @@ struct sbp2_status_block {
 #define SBP2_UNIT_SPEC_ID_ENTRY                        0x0000609e
 #define SBP2_SW_VERSION_ENTRY                  0x00010483
 
-
 /*
- * SCSI specific definitions
+ * The default maximum s/g segment size of a FireWire controller is
+ * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
+ * be quadlet-aligned, we set the length limit to 0xffff & ~3.
  */
+#define SBP2_MAX_SEG_SIZE                      0xfffc
 
-#define SBP2_MAX_SG_ELEMENT_LENGTH             0xf000
-/* There is no real limitation of the queue depth (i.e. length of the linked
+/*
+ * There is no real limitation of the queue depth (i.e. length of the linked
  * list of command ORBs) at the target. The chosen depth is merely an
- * implementation detail of the sbp2 driver. */
+ * implementation detail of the sbp2 driver.
+ */
 #define SBP2_MAX_CMDS                          8
 
 #define SBP2_SCSI_STATUS_GOOD                  0x0
@@ -240,12 +240,6 @@ struct sbp2_status_block {
  * Representations of commands and devices
  */
 
-enum sbp2_dma_types {
-       CMD_DMA_NONE,
-       CMD_DMA_PAGE,
-       CMD_DMA_SINGLE
-};
-
 /* Per SCSI command */
 struct sbp2_command_info {
        struct list_head list;
@@ -258,11 +252,6 @@ struct sbp2_command_info {
        struct sbp2_unrestricted_page_table
                scatter_gather_element[SG_ALL] __attribute__((aligned(8)));
        dma_addr_t sge_dma;
-       void *sge_buffer;
-       dma_addr_t cmd_dma;
-       enum sbp2_dma_types dma_type;
-       unsigned long dma_size;
-       enum dma_data_direction dma_dir;
 };
 
 /* Per FireWire host */
index 25db6e67fa4ea6d123f9a71df2e9c44616e84c3d..679a918a5cc76eae41500b458eef93cc2c06992a 100644 (file)
@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file *file,
                if (unlikely(d == NULL))
                        return -EFAULT;
 
-               if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
+               if (unlikely(v.buffer >= d->num_desc - 1)) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file *file,
                if (unlikely(d == NULL))
                        return -EFAULT;
 
-               if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
+               if (unlikely(v.buffer > d->num_desc - 1)) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file *file,
                d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
                if (d == NULL) return -EFAULT;
 
-               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
+               if (v.buffer >= d->num_desc - 1) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file *file,
                d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
                if (d == NULL) return -EFAULT;
 
-               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
+               if (v.buffer >= d->num_desc - 1) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -1341,9 +1341,8 @@ static void video1394_add_host (struct hpsb_host *host)
        hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
 
        minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
-       device_create_drvdata(hpsb_protocol_class, NULL,
-                             MKDEV(IEEE1394_MAJOR, minor), NULL,
-                             "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+       device_create(hpsb_protocol_class, NULL, MKDEV(IEEE1394_MAJOR, minor),
+                     NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 }
 
 
index 3cab0cedfca21f54d83027a78f1f6c6a3c1a1b8e..a78d35aecee3de339520308358d6ca565d69cdd1 100644 (file)
@@ -3691,9 +3691,9 @@ static void cm_add_one(struct ib_device *ib_device)
        cm_dev->ib_device = ib_device;
        cm_get_ack_delay(cm_dev);
 
-       cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
-                                              MKDEV(0, 0), NULL,
-                                              "%s", ib_device->name);
+       cm_dev->device = device_create(&cm_class, &ib_device->dev,
+                                      MKDEV(0, 0), NULL,
+                                      "%s", ib_device->name);
        if (!cm_dev->device) {
                kfree(cm_dev);
                return;
index 268a2d23b7c9a8e9092877ca319989891e99e90d..8c46f2257098cf2d7e01ba472c31a48dc5ffb77a 100644 (file)
@@ -1016,9 +1016,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
        if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
                goto err_cdev;
 
-       port->dev = device_create_drvdata(umad_class, device->dma_device,
-                                         port->cdev->dev, port,
-                                         "umad%d", port->dev_num);
+       port->dev = device_create(umad_class, device->dma_device,
+                                 port->cdev->dev, port,
+                                 "umad%d", port->dev_num);
        if (IS_ERR(port->dev))
                goto err_cdev;
 
@@ -1036,9 +1036,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
        if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
                goto err_sm_cdev;
 
-       port->sm_dev = device_create_drvdata(umad_class, device->dma_device,
-                                            port->sm_cdev->dev, port,
-                                            "issm%d", port->dev_num);
+       port->sm_dev = device_create(umad_class, device->dma_device,
+                                    port->sm_cdev->dev, port,
+                                    "issm%d", port->dev_num);
        if (IS_ERR(port->sm_dev))
                goto err_sm_cdev;
 
index aeee856c4060648f4898c4014d30ed2c73065bdd..d85af1b670274466f5ec13a518d8011da1cb7da0 100644 (file)
@@ -764,12 +764,9 @@ static void ib_uverbs_add_one(struct ib_device *device)
        if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
                goto err_cdev;
 
-       uverbs_dev->dev = device_create_drvdata(uverbs_class,
-                                               device->dma_device,
-                                               uverbs_dev->cdev->dev,
-                                               uverbs_dev,
-                                               "uverbs%d",
-                                               uverbs_dev->devnum);
+       uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
+                                       uverbs_dev->cdev->dev, uverbs_dev,
+                                       "uverbs%d", uverbs_dev->devnum);
        if (IS_ERR(uverbs_dev->dev))
                goto err_cdev;
 
index 56c0eda3c0772816f09e9b975090707929b826f3..1af1f3a907c6eb25a7930a6fd2e22ca36ad7135b 100644 (file)
@@ -2455,7 +2455,7 @@ static int init_cdev(int minor, char *name, const struct file_operations *fops,
                goto err_cdev;
        }
 
-       device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
+       device = device_create(ipath_class, NULL, dev, NULL, name);
 
        if (IS_ERR(device)) {
                ret = PTR_ERR(device);
index 078e4eed0894ba45a495184bb91b6518935663b9..2880eaae157a90896ce7785cea9b4e2c3c32dd4f 100644 (file)
@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport)
 enum gameport_event_type {
        GAMEPORT_REGISTER_PORT,
        GAMEPORT_REGISTER_DRIVER,
+       GAMEPORT_ATTACH_DRIVER,
 };
 
 struct gameport_event {
@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list);
 static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
 static struct task_struct *gameport_task;
 
-static void gameport_queue_event(void *object, struct module *owner,
-                             enum gameport_event_type event_type)
+static int gameport_queue_event(void *object, struct module *owner,
+                               enum gameport_event_type event_type)
 {
        unsigned long flags;
        struct gameport_event *event;
+       int retval = 0;
 
        spin_lock_irqsave(&gameport_event_lock, flags);
 
@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner,
                }
        }
 
-       if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) {
-               if (!try_module_get(owner)) {
-                       printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type);
-                       kfree(event);
-                       goto out;
-               }
-
-               event->type = event_type;
-               event->object = object;
-               event->owner = owner;
+       event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
+       if (!event) {
+               printk(KERN_ERR
+                       "gameport: Not enough memory to queue event %d\n",
+                       event_type);
+               retval = -ENOMEM;
+               goto out;
+       }
 
-               list_add_tail(&event->node, &gameport_event_list);
-               wake_up(&gameport_wait);
-       } else {
-               printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type);
+       if (!try_module_get(owner)) {
+               printk(KERN_WARNING
+                       "gameport: Can't get module reference, dropping event %d\n",
+                       event_type);
+               kfree(event);
+               retval = -EINVAL;
+               goto out;
        }
+
+       event->type = event_type;
+       event->object = object;
+       event->owner = owner;
+
+       list_add_tail(&event->node, &gameport_event_list);
+       wake_up(&gameport_wait);
+
 out:
        spin_unlock_irqrestore(&gameport_event_lock, flags);
+       return retval;
 }
 
 static void gameport_free_event(struct gameport_event *event)
@@ -378,9 +390,10 @@ static void gameport_handle_event(void)
 }
 
 /*
- * Remove all events that have been submitted for a given gameport port.
+ * Remove all events that have been submitted for a given object,
+ * be it a gameport port or a driver.
  */
-static void gameport_remove_pending_events(struct gameport *gameport)
+static void gameport_remove_pending_events(void *object)
 {
        struct list_head *node, *next;
        struct gameport_event *event;
@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport)
 
        list_for_each_safe(node, next, &gameport_event_list) {
                event = list_entry(node, struct gameport_event, node);
-               if (event->object == gameport) {
+               if (event->object == object) {
                        list_del_init(node);
                        gameport_free_event(event);
                }
@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv)
                        drv->driver.name, error);
 }
 
-void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
+int __gameport_register_driver(struct gameport_driver *drv, struct module *owner,
+                               const char *mod_name)
 {
+       int error;
+
        drv->driver.bus = &gameport_bus;
-       gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER);
+       drv->driver.owner = owner;
+       drv->driver.mod_name = mod_name;
+
+       /*
+        * Temporarily disable automatic binding because probing
+        * takes long time and we are better off doing it in kgameportd
+        */
+       drv->ignore = 1;
+
+       error = driver_register(&drv->driver);
+       if (error) {
+               printk(KERN_ERR
+                       "gameport: driver_register() failed for %s, error: %d\n",
+                       drv->driver.name, error);
+               return error;
+       }
+
+       /*
+        * Reset ignore flag and let kgameportd bind the driver to free ports
+        */
+       drv->ignore = 0;
+       error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER);
+       if (error) {
+               driver_unregister(&drv->driver);
+               return error;
+       }
+
+       return 0;
 }
 
 void gameport_unregister_driver(struct gameport_driver *drv)
@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv)
        struct gameport *gameport;
 
        mutex_lock(&gameport_mutex);
+
        drv->ignore = 1;        /* so gameport_find_driver ignores it */
+       gameport_remove_pending_events(drv);
 
 start_over:
        list_for_each_entry(gameport, &gameport_list, node) {
@@ -729,6 +774,7 @@ start_over:
        }
 
        driver_unregister(&drv->driver);
+
        mutex_unlock(&gameport_mutex);
 }
 
index 92498d470b1f7de7323eed8b87dfcd8dffa72d7e..6489f4010c4f2f6944090d8829b264bbd067901d 100644 (file)
@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = {
 
 static int __init a3d_init(void)
 {
-       gameport_register_driver(&a3d_drv);
-       return 0;
+       return gameport_register_driver(&a3d_drv);
 }
 
 static void __exit a3d_exit(void)
index d1ca8a14950f62f914e9d4f9f81ae34a7eabadfe..89c4c084d4ad8e86789b123302cd0350f0af7113 100644 (file)
@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = {
 
 static int __init adi_init(void)
 {
-       gameport_register_driver(&adi_drv);
-       return 0;
+       return gameport_register_driver(&adi_drv);
 }
 
 static void __exit adi_exit(void)
index 708c5ae13b24f33cb6b8b323996c2332d84520b7..356b3a25efa24c4568a909c59dedaa7ebcbc040c 100644 (file)
@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = {
 static int __init analog_init(void)
 {
        analog_parse_options();
-       gameport_register_driver(&analog_drv);
-
-       return 0;
+       return gameport_register_driver(&analog_drv);
 }
 
 static void __exit analog_exit(void)
index 639b975a8ed7a6c64ecb06f315dffa45eb2b5a1a..3497b87c3d0591c12446f16bc232337c3f367981 100644 (file)
@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = {
 
 static int __init cobra_init(void)
 {
-       gameport_register_driver(&cobra_drv);
-       return 0;
+       return gameport_register_driver(&cobra_drv);
 }
 
 static void __exit cobra_exit(void)
index cb6eef1f2d99f6d7b80a9f5e02d7411ececbd153..67c207f5b1a16cd56e88b140c63bbfdefb8f498b 100644 (file)
@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = {
 
 static int __init gf2k_init(void)
 {
-       gameport_register_driver(&gf2k_drv);
-       return 0;
+       return gameport_register_driver(&gf2k_drv);
 }
 
 static void __exit gf2k_exit(void)
index 684e07cfccc89a862d25897b9e0c760e5dd79965..fc55899ba6c50a8d5d4c8336d100ca51677d440f 100644 (file)
@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = {
 
 static int __init grip_init(void)
 {
-       gameport_register_driver(&grip_drv);
-       return 0;
+       return gameport_register_driver(&grip_drv);
 }
 
 static void __exit grip_exit(void)
index 8279481b16e7bbf038b70991dfe1d5ec6f16fff3..2d47baf47769843a98e23d9b47665560ef885e7f 100644 (file)
@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = {
 
 static int __init grip_init(void)
 {
-       gameport_register_driver(&grip_drv);
-       return 0;
+       return gameport_register_driver(&grip_drv);
 }
 
 static void __exit grip_exit(void)
index 25ec3fad9f2798d5126cec44e6b570a819152270..4058d4b272fe88fed73a2a3f0183b1d2cbeabd9b 100644 (file)
@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = {
 
 static int __init guillemot_init(void)
 {
-       gameport_register_driver(&guillemot_drv);
-       return 0;
+       return gameport_register_driver(&guillemot_drv);
 }
 
 static void __exit guillemot_exit(void)
index 8c3290b68205b933f76223ab139ed5a71aaeb518..2478289aeeea1b1c7c2cfec1ed8cde3544a1ae16 100644 (file)
@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = {
 
 static int __init interact_init(void)
 {
-       gameport_register_driver(&interact_drv);
-       return 0;
+       return gameport_register_driver(&interact_drv);
 }
 
 static void __exit interact_exit(void)
index 2a1b82c8b31c155c8c698741317a200b90898dcd..cd894a0564a2f06932954d7dcec2ff6c179a9d92 100644 (file)
@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = {
 
 static int __init joydump_init(void)
 {
-       gameport_register_driver(&joydump_drv);
-       return 0;
+       return gameport_register_driver(&joydump_drv);
 }
 
 static void __exit joydump_exit(void)
index 7b4865fdee54cdcf48998cff18dc7bdd4316a9c0..ca13a6bec33ef63fd904eaf3bd7b6853b2194dea 100644 (file)
@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = {
 
 static int __init sw_init(void)
 {
-       gameport_register_driver(&sw_drv);
-       return 0;
+       return gameport_register_driver(&sw_drv);
 }
 
 static void __exit sw_exit(void)
index 60c37bcb938d932d78bbd7a1065be2c6e335564f..d6c6098071150e02a456d1688c71fbf44a78cd91 100644 (file)
@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = {
 
 static int __init tmdc_init(void)
 {
-       gameport_register_driver(&tmdc_drv);
-       return 0;
+       return gameport_register_driver(&tmdc_drv);
 }
 
 static void __exit tmdc_exit(void)
index 6791be81eb2904b15780da13dac99ce11e5925a6..839d1c9622f66c1f4c1a217bf8a6c3c55503f990 100644 (file)
@@ -455,10 +455,10 @@ static void xpad_bulk_out(struct urb *urb)
        case -ENOENT:
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
-               dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down with status: %d", __func__, urb->status);
                break;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d", __func__, urb->status);
        }
 }
 
index b1ce10f50bcfcf7a14eca2c8c4cd9606efaecd90..22016ca153518b8c9535b11f215c59e1d0008880 100644 (file)
@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
 }
 
 /*
- * Most special keys (Fn+F?) on Dell Latitudes do not generate release
+ * Most special keys (Fn+F?) on Dell laptops do not generate release
  * events so we have to do it ourselves.
  */
-static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
+static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
 {
        const unsigned int forced_release_keys[] = {
                0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
@@ -1207,15 +1207,13 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
 {
        struct input_dev *old_dev, *new_dev;
        unsigned long value;
-       char *rest;
        int err;
        unsigned char old_extra, old_set;
 
        if (!atkbd->write)
                return -EIO;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        if (atkbd->extra != value) {
@@ -1264,12 +1262,10 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
 {
        struct input_dev *old_dev, *new_dev;
        unsigned long value;
-       char *rest;
        int err;
        unsigned char old_scroll;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        if (atkbd->scroll != value) {
@@ -1310,15 +1306,13 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
 {
        struct input_dev *old_dev, *new_dev;
        unsigned long value;
-       char *rest;
        int err;
        unsigned char old_set, old_extra;
 
        if (!atkbd->write)
                return -EIO;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || (value != 2 && value != 3))
+       if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))
                return -EINVAL;
 
        if (atkbd->set != value) {
@@ -1361,15 +1355,13 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
 {
        struct input_dev *old_dev, *new_dev;
        unsigned long value;
-       char *rest;
        int err;
        unsigned char old_softrepeat, old_softraw;
 
        if (!atkbd->write)
                return -EIO;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        if (atkbd->softrepeat != value) {
@@ -1413,12 +1405,10 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
 {
        struct input_dev *old_dev, *new_dev;
        unsigned long value;
-       char *rest;
        int err;
        unsigned char old_softraw;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        if (atkbd->softraw != value) {
@@ -1461,13 +1451,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
 
 static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
        {
-               .ident = "Dell Latitude series",
+               .ident = "Dell Laptop",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
                },
                .callback = atkbd_setup_fixup,
-               .driver_data = atkbd_latitude_keymap_fixup,
+               .driver_data = atkbd_dell_laptop_keymap_fixup,
        },
        {
                .ident = "HP 2133",
index e348cfccc17a9549105fcab813d644ef6aa322fd..19284016e0f4d1c2ce47e3f86f4a5f59e04445fc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * Modified:
- *               Copyright 2007 Analog Devices Inc.
+ *               Copyright 2007-2008 Analog Devices Inc.
  *
  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  *
@@ -81,6 +81,9 @@ struct bf54x_kpad {
        unsigned short *keycode;
        struct timer_list timer;
        unsigned int keyup_test_jiffies;
+       unsigned short kpad_msel;
+       unsigned short kpad_prescale;
+       unsigned short kpad_ctl;
 };
 
 static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,
@@ -360,6 +363,10 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
 
+       bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL();
+       bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE();
+       bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL();
+
        if (device_may_wakeup(&pdev->dev))
                enable_irq_wake(bf54x_kpad->irq);
 
@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *pdev)
 {
        struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
 
+       bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel);
+       bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale);
+       bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl);
+
        if (device_may_wakeup(&pdev->dev))
                disable_irq_wake(bf54x_kpad->irq);
 
index ec96b369dd7ac02ed3bb49dec3bcfe8e9c649ae1..05f3f43582c2c1e40658e2d8e6e77f8717210f38 100644 (file)
@@ -36,9 +36,10 @@ struct gpio_keys_drvdata {
        struct gpio_button_data data[0];
 };
 
-static void gpio_keys_report_event(struct gpio_keys_button *button,
-                                  struct input_dev *input)
+static void gpio_keys_report_event(struct gpio_button_data *bdata)
 {
+       struct gpio_keys_button *button = bdata->button;
+       struct input_dev *input = bdata->input;
        unsigned int type = button->type ?: EV_KEY;
        int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
 
@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _data)
 {
        struct gpio_button_data *data = (struct gpio_button_data *)_data;
 
-       gpio_keys_report_event(data->button, data->input);
+       gpio_keys_report_event(data);
 }
 
 static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 {
-       struct platform_device *pdev = dev_id;
-       struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
-       struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
-       int i;
+       struct gpio_button_data *bdata = dev_id;
+       struct gpio_keys_button *button = bdata->button;
 
-       for (i = 0; i < pdata->nbuttons; i++) {
-               struct gpio_keys_button *button = &pdata->buttons[i];
+       BUG_ON(irq != gpio_to_irq(button->gpio));
 
-               if (irq == gpio_to_irq(button->gpio)) {
-                       struct gpio_button_data *bdata = &ddata->data[i];
-
-                       if (button->debounce_interval)
-                               mod_timer(&bdata->timer,
-                                         jiffies +
-                                         msecs_to_jiffies(button->debounce_interval));
-                       else
-                               gpio_keys_report_event(button, bdata->input);
-
-                       return IRQ_HANDLED;
-               }
-       }
+       if (button->debounce_interval)
+               mod_timer(&bdata->timer,
+                       jiffies + msecs_to_jiffies(button->debounce_interval));
+       else
+               gpio_keys_report_event(bdata);
 
-       return IRQ_NONE;
+       return IRQ_HANDLED;
 }
 
 static int __devinit gpio_keys_probe(struct platform_device *pdev)
@@ -151,7 +141,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
                                    IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
                                        IRQF_TRIGGER_FALLING,
                                    button->desc ? button->desc : "gpio_keys",
-                                   pdev);
+                                   bdata);
                if (error) {
                        pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
                                irq, error);
@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 
  fail2:
        while (--i >= 0) {
-               free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
+               free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
                if (pdata->buttons[i].debounce_interval)
                        del_timer_sync(&ddata->data[i].timer);
                gpio_free(pdata->buttons[i].gpio);
@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
 
        for (i = 0; i < pdata->nbuttons; i++) {
                int irq = gpio_to_irq(pdata->buttons[i].gpio);
-               free_irq(irq, pdev);
+               free_irq(irq, &ddata->data[i]);
                if (pdata->buttons[i].debounce_interval)
                        del_timer_sync(&ddata->data[i].timer);
                gpio_free(pdata->buttons[i].gpio);
index dcea87a0bc5674e16b88502273b903d684800663..69e674ecf19a1b26ed9f0db46d9c176c5d43d273 100644 (file)
@@ -62,7 +62,7 @@ struct omap_kp {
        unsigned int debounce;
 };
 
-DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
+static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
 
 static int *keymap;
 static unsigned int *row_gpios;
@@ -72,12 +72,9 @@ static unsigned int *col_gpios;
 static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
 {
        int col;
-       for (col = 0; col < omap_kp->cols; col++) {
-               if (value & (1 << col))
-                       omap_set_gpio_dataout(col_gpios[col], 1);
-               else
-                       omap_set_gpio_dataout(col_gpios[col], 0);
-       }
+
+       for (col = 0; col < omap_kp->cols; col++)
+               gpio_set_value(col_gpios[col], value & (1 << col));
 }
 
 static u8 get_row_gpio_val(struct omap_kp *omap_kp)
@@ -86,7 +83,7 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp)
        u8 value = 0;
 
        for (row = 0; row < omap_kp->rows; row++) {
-               if (omap_get_gpio_datain(row_gpios[row]))
+               if (gpio_get_value(row_gpios[row]))
                        value |= (1 << row);
        }
        return value;
@@ -333,23 +330,23 @@ static int __init omap_kp_probe(struct platform_device *pdev)
        if (cpu_is_omap24xx()) {
                /* Cols: outputs */
                for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
-                       if (omap_request_gpio(col_gpios[col_idx]) < 0) {
+                       if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) {
                                printk(KERN_ERR "Failed to request"
                                       "GPIO%d for keypad\n",
                                       col_gpios[col_idx]);
                                goto err1;
                        }
-                       omap_set_gpio_direction(col_gpios[col_idx], 0);
+                       gpio_direction_output(col_gpios[col_idx], 0);
                }
                /* Rows: inputs */
                for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
-                       if (omap_request_gpio(row_gpios[row_idx]) < 0) {
+                       if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) {
                                printk(KERN_ERR "Failed to request"
                                       "GPIO%d for keypad\n",
                                       row_gpios[row_idx]);
                                goto err2;
                        }
-                       omap_set_gpio_direction(row_gpios[row_idx], 1);
+                       gpio_direction_input(row_gpios[row_idx]);
                }
        } else {
                col_idx = 0;
@@ -418,10 +415,10 @@ err3:
        device_remove_file(&pdev->dev, &dev_attr_enable);
 err2:
        for (i = row_idx - 1; i >=0; i--)
-               omap_free_gpio(row_gpios[i]);
+               gpio_free(row_gpios[i]);
 err1:
        for (i = col_idx - 1; i >=0; i--)
-               omap_free_gpio(col_gpios[i]);
+               gpio_free(col_gpios[i]);
 
        kfree(omap_kp);
        input_free_device(input_dev);
@@ -438,9 +435,9 @@ static int omap_kp_remove(struct platform_device *pdev)
        if (cpu_is_omap24xx()) {
                int i;
                for (i = 0; i < omap_kp->cols; i++)
-                       omap_free_gpio(col_gpios[i]);
+                       gpio_free(col_gpios[i]);
                for (i = 0; i < omap_kp->rows; i++) {
-                       omap_free_gpio(row_gpios[i]);
+                       gpio_free(row_gpios[i]);
                        free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
                }
        } else {
index e99b7882f3826e3d9f4563eb48ece92d8085fb03..199055db5082e8020834e8883e3d502d7319bfb8 100644 (file)
@@ -180,6 +180,19 @@ config INPUT_YEALINK
          To compile this driver as a module, choose M here: the module will be
          called yealink.
 
+config INPUT_CM109
+       tristate "C-Media CM109 USB I/O Controller"
+       depends on EXPERIMENTAL
+       depends on USB_ARCH_HAS_HCD
+       select USB
+       help
+         Say Y here if you want to enable keyboard and buzzer functions of the
+         C-Media CM109 usb phones. The audio part is enabled by the generic
+         usb sound driver, so you might want to enable that as well.
+
+         To compile this driver as a module, choose M here: the module will be
+         called cm109.
+
 config INPUT_UINPUT
        tristate "User level driver support"
        help
index f48009b52226ba94b69965daf1a9eaa968da5764..d7db2aeb8a982e82fe712ed17c3f663c62a2fc35 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2)               += ati_remote2.o
 obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)     += keyspan_remote.o
 obj-$(CONFIG_INPUT_POWERMATE)          += powermate.o
 obj-$(CONFIG_INPUT_YEALINK)            += yealink.o
+obj-$(CONFIG_INPUT_CM109)              += cm109.o
 obj-$(CONFIG_HP_SDC_RTC)               += hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
 obj-$(CONFIG_INPUT_APANEL)             += apanel.o
index a7fabafbd94c6e9fe3691db3b18caea49a835b88..3c9988dc0e9fcc98e05a35fc25744cfce84cdb4f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * ati_remote2 - ATI/Philips USB RF remote driver
  *
- * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
- * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk>
+ * Copyright (C) 2005-2008 Ville Syrjala <syrjala@sci.fi>
+ * Copyright (C) 2007-2008 Peter Stokes <linux@dadeos.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
@@ -12,7 +12,7 @@
 #include <linux/usb/input.h>
 
 #define DRIVER_DESC    "ATI/Philips USB RF remote driver"
-#define DRIVER_VERSION "0.2"
+#define DRIVER_VERSION "0.3"
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
@@ -27,7 +27,7 @@ MODULE_LICENSE("GPL");
  * A remote's "channel" may be altered by pressing and holding the "PC" button for
  * approximately 3 seconds, after which the button will slowly flash the count of the
  * currently configured "channel", using the numeric keypad enter a number between 1 and
- * 16 and then the "PC" button again, the button will slowly flash the count of the
+ * 16 and then press the "PC" button again, the button will slowly flash the count of the
  * newly configured "channel".
  */
 
@@ -45,9 +45,25 @@ static struct usb_device_id ati_remote2_id_table[] = {
 };
 MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
 
-static struct {
-       int hw_code;
-       int key_code;
+static DEFINE_MUTEX(ati_remote2_mutex);
+
+enum {
+       ATI_REMOTE2_OPENED = 0x1,
+       ATI_REMOTE2_SUSPENDED = 0x2,
+};
+
+enum {
+       ATI_REMOTE2_AUX1,
+       ATI_REMOTE2_AUX2,
+       ATI_REMOTE2_AUX3,
+       ATI_REMOTE2_AUX4,
+       ATI_REMOTE2_PC,
+       ATI_REMOTE2_MODES,
+};
+
+static const struct {
+       u8  hw_code;
+       u16 keycode;
 } ati_remote2_key_table[] = {
        { 0x00, KEY_0 },
        { 0x01, KEY_1 },
@@ -73,6 +89,7 @@ static struct {
        { 0x37, KEY_RECORD },
        { 0x38, KEY_DVD },
        { 0x39, KEY_TV },
+       { 0x3f, KEY_PROG1 }, /* AUX1-AUX4 and PC */
        { 0x54, KEY_MENU },
        { 0x58, KEY_UP },
        { 0x59, KEY_DOWN },
@@ -91,15 +108,9 @@ static struct {
        { 0xa9, BTN_LEFT },
        { 0xaa, BTN_RIGHT },
        { 0xbe, KEY_QUESTION },
-       { 0xd5, KEY_FRONT },
        { 0xd0, KEY_EDIT },
+       { 0xd5, KEY_FRONT },
        { 0xf9, KEY_INFO },
-       { (0x00 << 8) | 0x3f, KEY_PROG1 },
-       { (0x01 << 8) | 0x3f, KEY_PROG2 },
-       { (0x02 << 8) | 0x3f, KEY_PROG3 },
-       { (0x03 << 8) | 0x3f, KEY_PROG4 },
-       { (0x04 << 8) | 0x3f, KEY_PC },
-       { 0, KEY_RESERVED }
 };
 
 struct ati_remote2 {
@@ -117,46 +128,106 @@ struct ati_remote2 {
 
        char name[64];
        char phys[64];
+
+       /* Each mode (AUX1-AUX4 and PC) can have an independent keymap. */
+       u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
+
+       unsigned int flags;
 };
 
 static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
 static void ati_remote2_disconnect(struct usb_interface *interface);
+static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);
+static int ati_remote2_resume(struct usb_interface *interface);
 
 static struct usb_driver ati_remote2_driver = {
        .name       = "ati_remote2",
        .probe      = ati_remote2_probe,
        .disconnect = ati_remote2_disconnect,
        .id_table   = ati_remote2_id_table,
+       .suspend    = ati_remote2_suspend,
+       .resume     = ati_remote2_resume,
+       .supports_autosuspend = 1,
 };
 
-static int ati_remote2_open(struct input_dev *idev)
+static int ati_remote2_submit_urbs(struct ati_remote2 *ar2)
 {
-       struct ati_remote2 *ar2 = input_get_drvdata(idev);
        int r;
 
        r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
        if (r) {
                dev_err(&ar2->intf[0]->dev,
-                       "%s: usb_submit_urb() = %d\n", __func__, r);
+                       "%s(): usb_submit_urb() = %d\n", __func__, r);
                return r;
        }
        r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
        if (r) {
                usb_kill_urb(ar2->urb[0]);
                dev_err(&ar2->intf[1]->dev,
-                       "%s: usb_submit_urb() = %d\n", __func__, r);
+                       "%s(): usb_submit_urb() = %d\n", __func__, r);
                return r;
        }
 
        return 0;
 }
 
+static void ati_remote2_kill_urbs(struct ati_remote2 *ar2)
+{
+       usb_kill_urb(ar2->urb[1]);
+       usb_kill_urb(ar2->urb[0]);
+}
+
+static int ati_remote2_open(struct input_dev *idev)
+{
+       struct ati_remote2 *ar2 = input_get_drvdata(idev);
+       int r;
+
+       dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+       r = usb_autopm_get_interface(ar2->intf[0]);
+       if (r) {
+               dev_err(&ar2->intf[0]->dev,
+                       "%s(): usb_autopm_get_interface() = %d\n", __func__, r);
+               goto fail1;
+       }
+
+       mutex_lock(&ati_remote2_mutex);
+
+       if (!(ar2->flags & ATI_REMOTE2_SUSPENDED)) {
+               r = ati_remote2_submit_urbs(ar2);
+               if (r)
+                       goto fail2;
+       }
+
+       ar2->flags |= ATI_REMOTE2_OPENED;
+
+       mutex_unlock(&ati_remote2_mutex);
+
+       usb_autopm_put_interface(ar2->intf[0]);
+
+       return 0;
+
+ fail2:
+       mutex_unlock(&ati_remote2_mutex);
+       usb_autopm_put_interface(ar2->intf[0]);
+ fail1:
+       return r;
+}
+
 static void ati_remote2_close(struct input_dev *idev)
 {
        struct ati_remote2 *ar2 = input_get_drvdata(idev);
 
-       usb_kill_urb(ar2->urb[0]);
-       usb_kill_urb(ar2->urb[1]);
+       dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+       mutex_lock(&ati_remote2_mutex);
+
+       if (!(ar2->flags & ATI_REMOTE2_SUSPENDED))
+               ati_remote2_kill_urbs(ar2);
+
+       ar2->flags &= ~ATI_REMOTE2_OPENED;
+
+       mutex_unlock(&ati_remote2_mutex);
 }
 
 static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
@@ -172,7 +243,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
 
        mode = data[0] & 0x0F;
 
-       if (mode > 4) {
+       if (mode > ATI_REMOTE2_PC) {
                dev_err(&ar2->intf[0]->dev,
                        "Unknown mode byte (%02x %02x %02x %02x)\n",
                        data[3], data[2], data[1], data[0]);
@@ -191,7 +262,7 @@ static int ati_remote2_lookup(unsigned int hw_code)
 {
        int i;
 
-       for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+       for (i = 0; i < ARRAY_SIZE(ati_remote2_key_table); i++)
                if (ati_remote2_key_table[i].hw_code == hw_code)
                        return i;
 
@@ -211,7 +282,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
 
        mode = data[0] & 0x0F;
 
-       if (mode > 4) {
+       if (mode > ATI_REMOTE2_PC) {
                dev_err(&ar2->intf[1]->dev,
                        "Unknown mode byte (%02x %02x %02x %02x)\n",
                        data[3], data[2], data[1], data[0]);
@@ -219,10 +290,6 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
        }
 
        hw_code = data[2];
-       /*
-        * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
-        * Use the mode byte to figure out which one was pressed.
-        */
        if (hw_code == 0x3f) {
                /*
                 * For some incomprehensible reason the mouse pad generates
@@ -236,8 +303,6 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
 
                if (data[1] == 0)
                        ar2->mode = mode;
-
-               hw_code |= mode << 8;
        }
 
        if (!((1 << mode) & mode_mask))
@@ -260,8 +325,8 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
        case 2: /* repeat */
 
                /* No repeat for mouse buttons. */
-               if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
-                   ati_remote2_key_table[index].key_code == BTN_RIGHT)
+               if (ar2->keycode[mode][index] == BTN_LEFT ||
+                   ar2->keycode[mode][index] == BTN_RIGHT)
                        return;
 
                if (!time_after_eq(jiffies, ar2->jiffies))
@@ -276,7 +341,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
                return;
        }
 
-       input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
+       input_event(idev, EV_KEY, ar2->keycode[mode][index], data[1]);
        input_sync(idev);
 }
 
@@ -287,6 +352,7 @@ static void ati_remote2_complete_mouse(struct urb *urb)
 
        switch (urb->status) {
        case 0:
+               usb_mark_last_busy(ar2->udev);
                ati_remote2_input_mouse(ar2);
                break;
        case -ENOENT:
@@ -297,6 +363,7 @@ static void ati_remote2_complete_mouse(struct urb *urb)
                        "%s(): urb status = %d\n", __func__, urb->status);
                return;
        default:
+               usb_mark_last_busy(ar2->udev);
                dev_err(&ar2->intf[0]->dev,
                        "%s(): urb status = %d\n", __func__, urb->status);
        }
@@ -314,6 +381,7 @@ static void ati_remote2_complete_key(struct urb *urb)
 
        switch (urb->status) {
        case 0:
+               usb_mark_last_busy(ar2->udev);
                ati_remote2_input_key(ar2);
                break;
        case -ENOENT:
@@ -324,6 +392,7 @@ static void ati_remote2_complete_key(struct urb *urb)
                        "%s(): urb status = %d\n", __func__, urb->status);
                return;
        default:
+               usb_mark_last_busy(ar2->udev);
                dev_err(&ar2->intf[1]->dev,
                        "%s(): urb status = %d\n", __func__, urb->status);
        }
@@ -334,10 +403,60 @@ static void ati_remote2_complete_key(struct urb *urb)
                        "%s(): usb_submit_urb() = %d\n", __func__, r);
 }
 
+static int ati_remote2_getkeycode(struct input_dev *idev,
+                                 int scancode, int *keycode)
+{
+       struct ati_remote2 *ar2 = input_get_drvdata(idev);
+       int index, mode;
+
+       mode = scancode >> 8;
+       if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+               return -EINVAL;
+
+       index = ati_remote2_lookup(scancode & 0xFF);
+       if (index < 0)
+               return -EINVAL;
+
+       *keycode = ar2->keycode[mode][index];
+       return 0;
+}
+
+static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
+{
+       struct ati_remote2 *ar2 = input_get_drvdata(idev);
+       int index, mode, old_keycode;
+
+       mode = scancode >> 8;
+       if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+               return -EINVAL;
+
+       index = ati_remote2_lookup(scancode & 0xFF);
+       if (index < 0)
+               return -EINVAL;
+
+       if (keycode < KEY_RESERVED || keycode > KEY_MAX)
+               return -EINVAL;
+
+       old_keycode = ar2->keycode[mode][index];
+       ar2->keycode[mode][index] = keycode;
+       set_bit(keycode, idev->keybit);
+
+       for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) {
+               for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) {
+                       if (ar2->keycode[mode][index] == old_keycode)
+                               return 0;
+               }
+       }
+
+       clear_bit(old_keycode, idev->keybit);
+
+       return 0;
+}
+
 static int ati_remote2_input_init(struct ati_remote2 *ar2)
 {
        struct input_dev *idev;
-       int i, retval;
+       int index, mode, retval;
 
        idev = input_allocate_device();
        if (!idev)
@@ -350,8 +469,26 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
        idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
                BIT_MASK(BTN_RIGHT);
        idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-       for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
-               set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
+
+       for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) {
+               for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) {
+                       ar2->keycode[mode][index] = ati_remote2_key_table[index].keycode;
+                       set_bit(ar2->keycode[mode][index], idev->keybit);
+               }
+       }
+
+       /* AUX1-AUX4 and PC generate the same scancode. */
+       index = ati_remote2_lookup(0x3f);
+       ar2->keycode[ATI_REMOTE2_AUX1][index] = KEY_PROG1;
+       ar2->keycode[ATI_REMOTE2_AUX2][index] = KEY_PROG2;
+       ar2->keycode[ATI_REMOTE2_AUX3][index] = KEY_PROG3;
+       ar2->keycode[ATI_REMOTE2_AUX4][index] = KEY_PROG4;
+       ar2->keycode[ATI_REMOTE2_PC][index] = KEY_PC;
+       set_bit(KEY_PROG1, idev->keybit);
+       set_bit(KEY_PROG2, idev->keybit);
+       set_bit(KEY_PROG3, idev->keybit);
+       set_bit(KEY_PROG4, idev->keybit);
+       set_bit(KEY_PC, idev->keybit);
 
        idev->rep[REP_DELAY]  = 250;
        idev->rep[REP_PERIOD] = 33;
@@ -359,6 +496,9 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
        idev->open = ati_remote2_open;
        idev->close = ati_remote2_close;
 
+       idev->getkeycode = ati_remote2_getkeycode;
+       idev->setkeycode = ati_remote2_setkeycode;
+
        idev->name = ar2->name;
        idev->phys = ar2->phys;
 
@@ -490,6 +630,8 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
 
        usb_set_intfdata(interface, ar2);
 
+       interface->needs_remote_wakeup = 1;
+
        return 0;
 
  fail2:
@@ -522,6 +664,57 @@ static void ati_remote2_disconnect(struct usb_interface *interface)
        kfree(ar2);
 }
 
+static int ati_remote2_suspend(struct usb_interface *interface,
+                              pm_message_t message)
+{
+       struct ati_remote2 *ar2;
+       struct usb_host_interface *alt = interface->cur_altsetting;
+
+       if (alt->desc.bInterfaceNumber)
+               return 0;
+
+       ar2 = usb_get_intfdata(interface);
+
+       dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+       mutex_lock(&ati_remote2_mutex);
+
+       if (ar2->flags & ATI_REMOTE2_OPENED)
+               ati_remote2_kill_urbs(ar2);
+
+       ar2->flags |= ATI_REMOTE2_SUSPENDED;
+
+       mutex_unlock(&ati_remote2_mutex);
+
+       return 0;
+}
+
+static int ati_remote2_resume(struct usb_interface *interface)
+{
+       struct ati_remote2 *ar2;
+       struct usb_host_interface *alt = interface->cur_altsetting;
+       int r = 0;
+
+       if (alt->desc.bInterfaceNumber)
+               return 0;
+
+       ar2 = usb_get_intfdata(interface);
+
+       dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+       mutex_lock(&ati_remote2_mutex);
+
+       if (ar2->flags & ATI_REMOTE2_OPENED)
+               r = ati_remote2_submit_urbs(ar2);
+
+       if (!r)
+               ar2->flags &= ~ATI_REMOTE2_SUSPENDED;
+
+       mutex_unlock(&ati_remote2_mutex);
+
+       return r;
+}
+
 static int __init ati_remote2_init(void)
 {
        int r;
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
new file mode 100644 (file)
index 0000000..bce160f
--- /dev/null
@@ -0,0 +1,882 @@
+/*
+ * Driver for the VoIP USB phones with CM109 chipsets.
+ *
+ * Copyright (C) 2007 - 2008 Alfred E. Heggestad <aeh@db.org>
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+
+/*
+ *   Tested devices:
+ *     - Komunikate KIP1000
+ *     - Genius G-talk
+ *     - Allied-Telesis Corega USBPH01
+ *     - ...
+ *
+ * This driver is based on the yealink.c driver
+ *
+ * Thanks to:
+ *   - Authors of yealink.c
+ *   - Thomas Reitmayr
+ *   - Oliver Neukum for good review comments and code
+ *   - Shaun Jackman <sjackman@gmail.com> for Genius G-talk keymap
+ *   - Dmitry Torokhov for valuable input and review
+ *
+ * Todo:
+ *   - Read/write EEPROM
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/rwsem.h>
+#include <linux/usb/input.h>
+
+#define DRIVER_VERSION "20080805"
+#define DRIVER_AUTHOR  "Alfred E. Heggestad"
+#define DRIVER_DESC    "CM109 phone driver"
+
+static char *phone = "kip1000";
+module_param(phone, charp, S_IRUSR);
+MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01}");
+
+enum {
+       /* HID Registers */
+       HID_IR0 = 0x00, /* Record/Playback-mute button, Volume up/down  */
+       HID_IR1 = 0x01, /* GPI, generic registers or EEPROM_DATA0       */
+       HID_IR2 = 0x02, /* Generic registers or EEPROM_DATA1            */
+       HID_IR3 = 0x03, /* Generic registers or EEPROM_CTRL             */
+       HID_OR0 = 0x00, /* Mapping control, buzzer, SPDIF (offset 0x04) */
+       HID_OR1 = 0x01, /* GPO - General Purpose Output                 */
+       HID_OR2 = 0x02, /* Set GPIO to input/output mode                */
+       HID_OR3 = 0x03, /* SPDIF status channel or EEPROM_CTRL          */
+
+       /* HID_IR0 */
+       RECORD_MUTE   = 1 << 3,
+       PLAYBACK_MUTE = 1 << 2,
+       VOLUME_DOWN   = 1 << 1,
+       VOLUME_UP     = 1 << 0,
+
+       /* HID_OR0 */
+       /* bits 7-6
+          0: HID_OR1-2 are used for GPO; HID_OR0, 3 are used for buzzer
+             and SPDIF
+          1: HID_OR0-3 are used as generic HID registers
+          2: Values written to HID_OR0-3 are also mapped to MCU_CTRL,
+             EEPROM_DATA0-1, EEPROM_CTRL (see Note)
+          3: Reserved
+        */
+       HID_OR_GPO_BUZ_SPDIF   = 0 << 6,
+       HID_OR_GENERIC_HID_REG = 1 << 6,
+       HID_OR_MAP_MCU_EEPROM  = 2 << 6,
+
+       BUZZER_ON = 1 << 5,
+
+       /* up to 256 normal keys, up to 16 special keys */
+       KEYMAP_SIZE = 256 + 16,
+};
+
+/* CM109 protocol packet */
+struct cm109_ctl_packet {
+       u8 byte[4];
+} __attribute__ ((packed));
+
+enum { USB_PKT_LEN = sizeof(struct cm109_ctl_packet) };
+
+/* CM109 device structure */
+struct cm109_dev {
+       struct input_dev *idev;  /* input device */
+       struct usb_device *udev; /* usb device */
+       struct usb_interface *intf;
+
+       /* irq input channel */
+       struct cm109_ctl_packet *irq_data;
+       dma_addr_t irq_dma;
+       struct urb *urb_irq;
+
+       /* control output channel */
+       struct cm109_ctl_packet *ctl_data;
+       dma_addr_t ctl_dma;
+       struct usb_ctrlrequest *ctl_req;
+       dma_addr_t ctl_req_dma;
+       struct urb *urb_ctl;
+       /*
+        * The 3 bitfields below are protected by ctl_submit_lock.
+        * They have to be separate since they are accessed from IRQ
+        * context.
+        */
+       unsigned irq_urb_pending:1;     /* irq_urb is in flight */
+       unsigned ctl_urb_pending:1;     /* ctl_urb is in flight */
+       unsigned buzzer_pending:1;      /* need to issue buzz command */
+       spinlock_t ctl_submit_lock;
+
+       unsigned char buzzer_state;     /* on/off */
+
+       /* flags */
+       unsigned open:1;
+       unsigned resetting:1;
+       unsigned shutdown:1;
+
+       /* This mutex protects writes to the above flags */
+       struct mutex pm_mutex;
+
+       unsigned short keymap[KEYMAP_SIZE];
+
+       char phys[64];          /* physical device path */
+       int key_code;           /* last reported key */
+       int keybit;             /* 0=new scan  1,2,4,8=scan columns  */
+       u8 gpi;                 /* Cached value of GPI (high nibble) */
+};
+
+/******************************************************************************
+ * CM109 key interface
+ *****************************************************************************/
+
+static unsigned short special_keymap(int code)
+{
+       if (code > 0xff) {
+               switch (code - 0xff) {
+               case RECORD_MUTE:       return KEY_MUTE;
+               case PLAYBACK_MUTE:     return KEY_MUTE;
+               case VOLUME_DOWN:       return KEY_VOLUMEDOWN;
+               case VOLUME_UP:         return KEY_VOLUMEUP;
+               }
+       }
+       return KEY_RESERVED;
+}
+
+/* Map device buttons to internal key events.
+ *
+ * The "up" and "down" keys, are symbolised by arrows on the button.
+ * The "pickup" and "hangup" keys are symbolised by a green and red phone
+ * on the button.
+
+ Komunikate KIP1000 Keyboard Matrix
+
+     -> -- 1 -- 2 -- 3  --> GPI pin 4 (0x10)
+      |    |    |    |
+     <- -- 4 -- 5 -- 6  --> GPI pin 5 (0x20)
+      |    |    |    |
+     END - 7 -- 8 -- 9  --> GPI pin 6 (0x40)
+      |    |    |    |
+     OK -- * -- 0 -- #  --> GPI pin 7 (0x80)
+      |    |    |    |
+
+     /|\  /|\  /|\  /|\
+      |    |    |    |
+GPO
+pin:  3    2    1    0
+     0x8  0x4  0x2  0x1
+
+ */
+static unsigned short keymap_kip1000(int scancode)
+{
+       switch (scancode) {                             /* phone key:   */
+       case 0x82: return KEY_NUMERIC_0;                /*   0          */
+       case 0x14: return KEY_NUMERIC_1;                /*   1          */
+       case 0x12: return KEY_NUMERIC_2;                /*   2          */
+       case 0x11: return KEY_NUMERIC_3;                /*   3          */
+       case 0x24: return KEY_NUMERIC_4;                /*   4          */
+       case 0x22: return KEY_NUMERIC_5;                /*   5          */
+       case 0x21: return KEY_NUMERIC_6;                /*   6          */
+       case 0x44: return KEY_NUMERIC_7;                /*   7          */
+       case 0x42: return KEY_NUMERIC_8;                /*   8          */
+       case 0x41: return KEY_NUMERIC_9;                /*   9          */
+       case 0x81: return KEY_NUMERIC_POUND;            /*   #          */
+       case 0x84: return KEY_NUMERIC_STAR;             /*   *          */
+       case 0x88: return KEY_ENTER;                    /*   pickup     */
+       case 0x48: return KEY_ESC;                      /*   hangup     */
+       case 0x28: return KEY_LEFT;                     /*   IN         */
+       case 0x18: return KEY_RIGHT;                    /*   OUT        */
+       default:   return special_keymap(scancode);
+       }
+}
+
+/*
+  Contributed by Shaun Jackman <sjackman@gmail.com>
+
+  Genius G-Talk keyboard matrix
+     0 1 2 3
+  4: 0 4 8 Talk
+  5: 1 5 9 End
+  6: 2 6 # Up
+  7: 3 7 * Down
+*/
+static unsigned short keymap_gtalk(int scancode)
+{
+       switch (scancode) {
+       case 0x11: return KEY_NUMERIC_0;
+       case 0x21: return KEY_NUMERIC_1;
+       case 0x41: return KEY_NUMERIC_2;
+       case 0x81: return KEY_NUMERIC_3;
+       case 0x12: return KEY_NUMERIC_4;
+       case 0x22: return KEY_NUMERIC_5;
+       case 0x42: return KEY_NUMERIC_6;
+       case 0x82: return KEY_NUMERIC_7;
+       case 0x14: return KEY_NUMERIC_8;
+       case 0x24: return KEY_NUMERIC_9;
+       case 0x44: return KEY_NUMERIC_POUND;    /* # */
+       case 0x84: return KEY_NUMERIC_STAR;     /* * */
+       case 0x18: return KEY_ENTER;            /* Talk (green handset) */
+       case 0x28: return KEY_ESC;              /* End (red handset) */
+       case 0x48: return KEY_UP;               /* Menu up (rocker switch) */
+       case 0x88: return KEY_DOWN;             /* Menu down (rocker switch) */
+       default:   return special_keymap(scancode);
+       }
+}
+
+/*
+ * Keymap for Allied-Telesis Corega USBPH01
+ * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html
+ *
+ * Contributed by july@nat.bg
+ */
+static unsigned short keymap_usbph01(int scancode)
+{
+       switch (scancode) {
+       case 0x11: return KEY_NUMERIC_0;                /*   0          */
+       case 0x21: return KEY_NUMERIC_1;                /*   1          */
+       case 0x41: return KEY_NUMERIC_2;                /*   2          */
+       case 0x81: return KEY_NUMERIC_3;                /*   3          */
+       case 0x12: return KEY_NUMERIC_4;                /*   4          */
+       case 0x22: return KEY_NUMERIC_5;                /*   5          */
+       case 0x42: return KEY_NUMERIC_6;                /*   6          */
+       case 0x82: return KEY_NUMERIC_7;                /*   7          */
+       case 0x14: return KEY_NUMERIC_8;                /*   8          */
+       case 0x24: return KEY_NUMERIC_9;                /*   9          */
+       case 0x44: return KEY_NUMERIC_POUND;            /*   #          */
+       case 0x84: return KEY_NUMERIC_STAR;             /*   *          */
+       case 0x18: return KEY_ENTER;                    /*   pickup     */
+       case 0x28: return KEY_ESC;                      /*   hangup     */
+       case 0x48: return KEY_LEFT;                     /*   IN         */
+       case 0x88: return KEY_RIGHT;                    /*   OUT        */
+       default:   return special_keymap(scancode);
+       }
+}
+
+static unsigned short (*keymap)(int) = keymap_kip1000;
+
+/*
+ * Completes a request by converting the data into events for the
+ * input subsystem.
+ */
+static void report_key(struct cm109_dev *dev, int key)
+{
+       struct input_dev *idev = dev->idev;
+
+       if (dev->key_code >= 0) {
+               /* old key up */
+               input_report_key(idev, dev->key_code, 0);
+       }
+
+       dev->key_code = key;
+       if (key >= 0) {
+               /* new valid key */
+               input_report_key(idev, key, 1);
+       }
+
+       input_sync(idev);
+}
+
+/******************************************************************************
+ * CM109 usb communication interface
+ *****************************************************************************/
+
+static void cm109_submit_buzz_toggle(struct cm109_dev *dev)
+{
+       int error;
+
+       if (dev->buzzer_state)
+               dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
+       else
+               dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
+
+       error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
+       if (error)
+               err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
+}
+
+/*
+ * IRQ handler
+ */
+static void cm109_urb_irq_callback(struct urb *urb)
+{
+       struct cm109_dev *dev = urb->context;
+       const int status = urb->status;
+       int error;
+
+       dev_dbg(&urb->dev->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
+            dev->irq_data->byte[0],
+            dev->irq_data->byte[1],
+            dev->irq_data->byte[2],
+            dev->irq_data->byte[3],
+            dev->keybit);
+
+       if (status) {
+               if (status == -ESHUTDOWN)
+                       return;
+               err("%s: urb status %d", __func__, status);
+       }
+
+       /* Special keys */
+       if (dev->irq_data->byte[HID_IR0] & 0x0f) {
+               const int code = (dev->irq_data->byte[HID_IR0] & 0x0f);
+               report_key(dev, dev->keymap[0xff + code]);
+       }
+
+       /* Scan key column */
+       if (dev->keybit == 0xf) {
+
+               /* Any changes ? */
+               if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0))
+                       goto out;
+
+               dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0;
+               dev->keybit = 0x1;
+       } else {
+               report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]);
+
+               dev->keybit <<= 1;
+               if (dev->keybit > 0x8)
+                       dev->keybit = 0xf;
+       }
+
+ out:
+
+       spin_lock(&dev->ctl_submit_lock);
+
+       dev->irq_urb_pending = 0;
+
+       if (likely(!dev->shutdown)) {
+
+               if (dev->buzzer_state)
+                       dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
+               else
+                       dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
+
+               dev->ctl_data->byte[HID_OR1] = dev->keybit;
+               dev->ctl_data->byte[HID_OR2] = dev->keybit;
+
+               dev->buzzer_pending = 0;
+               dev->ctl_urb_pending = 1;
+
+               error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
+               if (error)
+                       err("%s: usb_submit_urb (urb_ctl) failed %d",
+                               __func__, error);
+       }
+
+       spin_unlock(&dev->ctl_submit_lock);
+}
+
+static void cm109_urb_ctl_callback(struct urb *urb)
+{
+       struct cm109_dev *dev = urb->context;
+       const int status = urb->status;
+       int error;
+
+       dev_dbg(&urb->dev->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
+            dev->ctl_data->byte[0],
+            dev->ctl_data->byte[1],
+            dev->ctl_data->byte[2],
+            dev->ctl_data->byte[3]);
+
+       if (status)
+               err("%s: urb status %d", __func__, status);
+
+       spin_lock(&dev->ctl_submit_lock);
+
+       dev->ctl_urb_pending = 0;
+
+       if (likely(!dev->shutdown)) {
+
+               if (dev->buzzer_pending) {
+                       dev->buzzer_pending = 0;
+                       dev->ctl_urb_pending = 1;
+                       cm109_submit_buzz_toggle(dev);
+               } else if (likely(!dev->irq_urb_pending)) {
+                       /* ask for key data */
+                       dev->irq_urb_pending = 1;
+                       error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC);
+                       if (error)
+                               err("%s: usb_submit_urb (urb_irq) failed %d",
+                                       __func__, error);
+               }
+       }
+
+       spin_unlock(&dev->ctl_submit_lock);
+}
+
+static void cm109_toggle_buzzer_async(struct cm109_dev *dev)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->ctl_submit_lock, flags);
+
+       if (dev->ctl_urb_pending) {
+               /* URB completion will resubmit */
+               dev->buzzer_pending = 1;
+       } else {
+               dev->ctl_urb_pending = 1;
+               cm109_submit_buzz_toggle(dev);
+       }
+
+       spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
+}
+
+static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on)
+{
+       int error;
+
+       if (on)
+               dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
+       else
+               dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
+
+       error = usb_control_msg(dev->udev,
+                               usb_sndctrlpipe(dev->udev, 0),
+                               dev->ctl_req->bRequest,
+                               dev->ctl_req->bRequestType,
+                               le16_to_cpu(dev->ctl_req->wValue),
+                               le16_to_cpu(dev->ctl_req->wIndex),
+                               dev->ctl_data,
+                               USB_PKT_LEN, USB_CTRL_SET_TIMEOUT);
+       if (error && error != EINTR)
+               err("%s: usb_control_msg() failed %d", __func__, error);
+}
+
+static void cm109_stop_traffic(struct cm109_dev *dev)
+{
+       dev->shutdown = 1;
+       /*
+        * Make sure other CPUs see this
+        */
+       smp_wmb();
+
+       usb_kill_urb(dev->urb_ctl);
+       usb_kill_urb(dev->urb_irq);
+
+       cm109_toggle_buzzer_sync(dev, 0);
+
+       dev->shutdown = 0;
+       smp_wmb();
+}
+
+static void cm109_restore_state(struct cm109_dev *dev)
+{
+       if (dev->open) {
+               /*
+                * Restore buzzer state.
+                * This will also kick regular URB submission
+                */
+               cm109_toggle_buzzer_async(dev);
+       }
+}
+
+/******************************************************************************
+ * input event interface
+ *****************************************************************************/
+
+static int cm109_input_open(struct input_dev *idev)
+{
+       struct cm109_dev *dev = input_get_drvdata(idev);
+       int error;
+
+       error = usb_autopm_get_interface(dev->intf);
+       if (error < 0) {
+               err("%s - cannot autoresume, result %d",
+                   __func__, error);
+               return error;
+       }
+
+       mutex_lock(&dev->pm_mutex);
+
+       dev->buzzer_state = 0;
+       dev->key_code = -1;     /* no keys pressed */
+       dev->keybit = 0xf;
+
+       /* issue INIT */
+       dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF;
+       dev->ctl_data->byte[HID_OR1] = dev->keybit;
+       dev->ctl_data->byte[HID_OR2] = dev->keybit;
+       dev->ctl_data->byte[HID_OR3] = 0x00;
+
+       error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL);
+       if (error)
+               err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
+       else
+               dev->open = 1;
+
+       mutex_unlock(&dev->pm_mutex);
+
+       if (error)
+               usb_autopm_put_interface(dev->intf);
+
+       return error;
+}
+
+static void cm109_input_close(struct input_dev *idev)
+{
+       struct cm109_dev *dev = input_get_drvdata(idev);
+
+       mutex_lock(&dev->pm_mutex);
+
+       /*
+        * Once we are here event delivery is stopped so we
+        * don't need to worry about someone starting buzzer
+        * again
+        */
+       cm109_stop_traffic(dev);
+       dev->open = 0;
+
+       mutex_unlock(&dev->pm_mutex);
+
+       usb_autopm_put_interface(dev->intf);
+}
+
+static int cm109_input_ev(struct input_dev *idev, unsigned int type,
+                         unsigned int code, int value)
+{
+       struct cm109_dev *dev = input_get_drvdata(idev);
+
+       dev_dbg(&dev->udev->dev,
+               "input_ev: type=%u code=%u value=%d\n", type, code, value);
+
+       if (type != EV_SND)
+               return -EINVAL;
+
+       switch (code) {
+       case SND_TONE:
+       case SND_BELL:
+               dev->buzzer_state = !!value;
+               if (!dev->resetting)
+                       cm109_toggle_buzzer_async(dev);
+               return 0;
+
+       default:
+               return -EINVAL;
+       }
+}
+
+
+/******************************************************************************
+ * Linux interface and usb initialisation
+ *****************************************************************************/
+
+struct driver_info {
+       char *name;
+};
+
+static const struct driver_info info_cm109 = {
+       .name = "CM109 USB driver",
+};
+
+enum {
+       VENDOR_ID        = 0x0d8c, /* C-Media Electronics */
+       PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */
+};
+
+/* table of devices that work with this driver */
+static const struct usb_device_id cm109_usb_table[] = {
+       {
+               .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                               USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor = VENDOR_ID,
+               .idProduct = PRODUCT_ID_CM109,
+               .bInterfaceClass = USB_CLASS_HID,
+               .bInterfaceSubClass = 0,
+               .bInterfaceProtocol = 0,
+               .driver_info = (kernel_ulong_t) &info_cm109
+       },
+       /* you can add more devices here with product ID 0x0008 - 0x000f */
+       { }
+};
+
+static void cm109_usb_cleanup(struct cm109_dev *dev)
+{
+       if (dev->ctl_req)
+               usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)),
+                               dev->ctl_req, dev->ctl_req_dma);
+       if (dev->ctl_data)
+               usb_buffer_free(dev->udev, USB_PKT_LEN,
+                               dev->ctl_data, dev->ctl_dma);
+       if (dev->irq_data)
+               usb_buffer_free(dev->udev, USB_PKT_LEN,
+                               dev->irq_data, dev->irq_dma);
+
+       usb_free_urb(dev->urb_irq);     /* parameter validation in core/urb */
+       usb_free_urb(dev->urb_ctl);     /* parameter validation in core/urb */
+       kfree(dev);
+}
+
+static void cm109_usb_disconnect(struct usb_interface *interface)
+{
+       struct cm109_dev *dev = usb_get_intfdata(interface);
+
+       usb_set_intfdata(interface, NULL);
+       input_unregister_device(dev->idev);
+       cm109_usb_cleanup(dev);
+}
+
+static int cm109_usb_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct driver_info *nfo = (struct driver_info *)id->driver_info;
+       struct usb_host_interface *interface;
+       struct usb_endpoint_descriptor *endpoint;
+       struct cm109_dev *dev;
+       struct input_dev *input_dev = NULL;
+       int ret, pipe, i;
+       int error = -ENOMEM;
+
+       interface = intf->cur_altsetting;
+       endpoint = &interface->endpoint[0].desc;
+
+       if (!usb_endpoint_is_int_in(endpoint))
+               return -ENODEV;
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       spin_lock_init(&dev->ctl_submit_lock);
+       mutex_init(&dev->pm_mutex);
+
+       dev->udev = udev;
+       dev->intf = intf;
+
+       dev->idev = input_dev = input_allocate_device();
+       if (!input_dev)
+               goto err_out;
+
+       /* allocate usb buffers */
+       dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+                                        GFP_KERNEL, &dev->irq_dma);
+       if (!dev->irq_data)
+               goto err_out;
+
+       dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+                                        GFP_KERNEL, &dev->ctl_dma);
+       if (!dev->ctl_data)
+               goto err_out;
+
+       dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)),
+                                       GFP_KERNEL, &dev->ctl_req_dma);
+       if (!dev->ctl_req)
+               goto err_out;
+
+       /* allocate urb structures */
+       dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
+       if (!dev->urb_irq)
+               goto err_out;
+
+       dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
+       if (!dev->urb_ctl)
+               goto err_out;
+
+       /* get a handle to the interrupt data pipe */
+       pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+       ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+       if (ret != USB_PKT_LEN)
+               err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
+
+       /* initialise irq urb */
+       usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data,
+                        USB_PKT_LEN,
+                        cm109_urb_irq_callback, dev, endpoint->bInterval);
+       dev->urb_irq->transfer_dma = dev->irq_dma;
+       dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       dev->urb_irq->dev = udev;
+
+       /* initialise ctl urb */
+       dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
+                                       USB_DIR_OUT;
+       dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
+       dev->ctl_req->wValue = cpu_to_le16(0x200);
+       dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
+       dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
+
+       usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
+                            (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN,
+                            cm109_urb_ctl_callback, dev);
+       dev->urb_ctl->setup_dma = dev->ctl_req_dma;
+       dev->urb_ctl->transfer_dma = dev->ctl_dma;
+       dev->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP |
+                                       URB_NO_TRANSFER_DMA_MAP;
+       dev->urb_ctl->dev = udev;
+
+       /* find out the physical bus location */
+       usb_make_path(udev, dev->phys, sizeof(dev->phys));
+       strlcat(dev->phys, "/input0", sizeof(dev->phys));
+
+       /* register settings for the input device */
+       input_dev->name = nfo->name;
+       input_dev->phys = dev->phys;
+       usb_to_input_id(udev, &input_dev->id);
+       input_dev->dev.parent = &intf->dev;
+
+       input_set_drvdata(input_dev, dev);
+       input_dev->open = cm109_input_open;
+       input_dev->close = cm109_input_close;
+       input_dev->event = cm109_input_ev;
+
+       input_dev->keycode = dev->keymap;
+       input_dev->keycodesize = sizeof(unsigned char);
+       input_dev->keycodemax = ARRAY_SIZE(dev->keymap);
+
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND);
+       input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
+
+       /* register available key events */
+       for (i = 0; i < KEYMAP_SIZE; i++) {
+               unsigned short k = keymap(i);
+               dev->keymap[i] = k;
+               __set_bit(k, input_dev->keybit);
+       }
+       __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+       error = input_register_device(dev->idev);
+       if (error)
+               goto err_out;
+
+       usb_set_intfdata(intf, dev);
+
+       return 0;
+
+ err_out:
+       input_free_device(input_dev);
+       cm109_usb_cleanup(dev);
+       return error;
+}
+
+static int cm109_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct cm109_dev *dev = usb_get_intfdata(intf);
+
+       dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event);
+
+       mutex_lock(&dev->pm_mutex);
+       cm109_stop_traffic(dev);
+       mutex_unlock(&dev->pm_mutex);
+
+       return 0;
+}
+
+static int cm109_usb_resume(struct usb_interface *intf)
+{
+       struct cm109_dev *dev = usb_get_intfdata(intf);
+
+       dev_info(&intf->dev, "cm109: usb_resume\n");
+
+       mutex_lock(&dev->pm_mutex);
+       cm109_restore_state(dev);
+       mutex_unlock(&dev->pm_mutex);
+
+       return 0;
+}
+
+static int cm109_usb_pre_reset(struct usb_interface *intf)
+{
+       struct cm109_dev *dev = usb_get_intfdata(intf);
+
+       mutex_lock(&dev->pm_mutex);
+
+       /*
+        * Make sure input events don't try to toggle buzzer
+        * while we are resetting
+        */
+       dev->resetting = 1;
+       smp_wmb();
+
+       cm109_stop_traffic(dev);
+
+       return 0;
+}
+
+static int cm109_usb_post_reset(struct usb_interface *intf)
+{
+       struct cm109_dev *dev = usb_get_intfdata(intf);
+
+       dev->resetting = 0;
+       smp_wmb();
+
+       cm109_restore_state(dev);
+
+       mutex_unlock(&dev->pm_mutex);
+
+       return 0;
+}
+
+static struct usb_driver cm109_driver = {
+       .name           = "cm109",
+       .probe          = cm109_usb_probe,
+       .disconnect     = cm109_usb_disconnect,
+       .suspend        = cm109_usb_suspend,
+       .resume         = cm109_usb_resume,
+       .reset_resume   = cm109_usb_resume,
+       .pre_reset      = cm109_usb_pre_reset,
+       .post_reset     = cm109_usb_post_reset,
+       .id_table       = cm109_usb_table,
+       .supports_autosuspend = 1,
+};
+
+static int __init cm109_select_keymap(void)
+{
+       /* Load the phone keymap */
+       if (!strcasecmp(phone, "kip1000")) {
+               keymap = keymap_kip1000;
+               printk(KERN_INFO KBUILD_MODNAME ": "
+                       "Keymap for Komunikate KIP1000 phone loaded\n");
+       } else if (!strcasecmp(phone, "gtalk")) {
+               keymap = keymap_gtalk;
+               printk(KERN_INFO KBUILD_MODNAME ": "
+                       "Keymap for Genius G-talk phone loaded\n");
+       } else if (!strcasecmp(phone, "usbph01")) {
+               keymap = keymap_usbph01;
+               printk(KERN_INFO KBUILD_MODNAME ": "
+                       "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n");
+       } else {
+               printk(KERN_ERR KBUILD_MODNAME ": "
+                       "Unsupported phone: %s\n", phone);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int __init cm109_init(void)
+{
+       int err;
+
+       err = cm109_select_keymap();
+       if (err)
+               return err;
+
+       err = usb_register(&cm109_driver);
+       if (err)
+               return err;
+
+       printk(KERN_INFO KBUILD_MODNAME ": "
+               DRIVER_DESC ": " DRIVER_VERSION " (C) " DRIVER_AUTHOR "\n");
+
+       return 0;
+}
+
+static void __exit cm109_exit(void)
+{
+       usb_deregister(&cm109_driver);
+}
+
+module_init(cm109_init);
+module_exit(cm109_exit);
+
+MODULE_DEVICE_TABLE(usb, cm109_usb_table);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
index fe268be3293b666e82b1e567bb645fb5847a3c5f..7c8957dd22c03d42252e410af97e385c78b2c4b7 100644 (file)
@@ -277,6 +277,16 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
        { KE_END,  0 }
 };
 
+static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = {
+       { KE_KEY,       0x01, {KEY_HELP} },          /* Fn+F1 */
+       { KE_KEY,       0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */
+       { KE_BLUETOOTH, 0x30 },                      /* Fn+F10 */
+       { KE_KEY,       0x31, {KEY_MAIL} },          /* mail button */
+       { KE_KEY,       0x36, {KEY_WWW} },           /* www button */
+       { KE_WIFI,      0x78 },                      /* satelite dish button */
+       { KE_END,       0 }
+};
+
 static struct key_entry keymap_fujitsu_n3510[] __initdata = {
        { KE_KEY, 0x11, {KEY_PROG1} },
        { KE_KEY, 0x12, {KEY_PROG2} },
@@ -616,6 +626,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
                },
                .driver_data = keymap_fs_amilo_pro_v2000
        },
+       {
+               .callback = dmi_matched,
+               .ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
+               },
+               .driver_data = keymap_fs_amilo_pro_v3505
+       },
        {
                .callback = dmi_matched,
                .ident = "Fujitsu-Siemens Amilo M7400",
index facefd3dba29a1aab6c4428c6bdef9a2a3aa1b55..11b5c7e84ed139ad9af9fe21fccc04927edd2a31 100644 (file)
@@ -52,8 +52,8 @@
 #include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/usb/input.h>
+#include <linux/map_to_7segment.h>
 
-#include "map_to_7segment.h"
 #include "yealink.h"
 
 #define DRIVER_VERSION "yld-20051230"
index f996546fc443757151f4f7f09f95c996f4c576d9..f488b6852baf78840c31fccf413ca63445965ac2 100644 (file)
@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
 
          If unsure, say N.
 
+config MOUSE_PS2_OLPC
+       bool "OLPC PS/2 mouse protocol extension"
+       depends on MOUSE_PS2 && OLPC
+       help
+         Say Y here if you have an OLPC XO-1 laptop (with built-in
+         PS/2 touchpad/tablet device).  The manufacturer calls the
+         touchpad an HGPK.
+
+         If unsure, say N.
+
 config MOUSE_SERIAL
        tristate "Serial mouse"
        select SERIO
index d4d202516090be6075afd735663ded497c7b6b0d..8e6e690978016b0dfae3f89276e05273764665b5 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_MOUSE_GPIO)      += gpio_mouse.o
 psmouse-objs := psmouse-base.o synaptics.o
 
 psmouse-$(CONFIG_MOUSE_PS2_ALPS)       += alps.o
+psmouse-$(CONFIG_MOUSE_PS2_OLPC)       += hgpk.o
 psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP)  += logips2pp.o
 psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK)   += lifebook.o
 psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
index 385e32bcf6a6e0ed7328f8c7ffd39badb7e4d45e..cbedf957cc58a380b71dad024b58710f5b2b0912 100644 (file)
@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
        { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
        { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
        { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
+       { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
        { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
 };
 
index 1f41ae94f26bdf216a5f667e754b3c559831e7ed..079816e6b23b042bff9a883aa984ffea757ee5a6 100644 (file)
@@ -136,12 +136,28 @@ MODULE_DEVICE_TABLE(usb, atp_table);
 #define ATP_GEYSER_MODE_REQUEST_INDEX          0
 #define ATP_GEYSER_MODE_VENDOR_VALUE           0x04
 
+/**
+ * enum atp_status_bits - status bit meanings
+ *
+ * These constants represent the meaning of the status bits.
+ * (only Geyser 3/4)
+ *
+ * @ATP_STATUS_BUTTON: The button was pressed
+ * @ATP_STATUS_BASE_UPDATE: Update of the base values (untouched pad)
+ * @ATP_STATUS_FROM_RESET: Reset previously performed
+ */
+enum atp_status_bits {
+       ATP_STATUS_BUTTON       = BIT(0),
+       ATP_STATUS_BASE_UPDATE  = BIT(2),
+       ATP_STATUS_FROM_RESET   = BIT(4),
+};
+
 /* Structure to hold all of our device specific stuff */
 struct atp {
        char                    phys[64];
        struct usb_device       *udev;          /* usb device */
        struct urb              *urb;           /* usb request block */
-       signed char             *data;          /* transferred data */
+       u8                      *data;          /* transferred data */
        struct input_dev        *input;         /* input dev */
        enum atp_touchpad_type  type;           /* type of touchpad */
        bool                    open;
@@ -251,8 +267,6 @@ static void atp_reinit(struct work_struct *work)
        int retval;
 
        dprintk("appletouch: putting appletouch to sleep (reinit)\n");
-       dev->idlecount = 0;
-
        atp_geyser_init(udev);
 
        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -327,11 +341,14 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
        input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
 }
 
-static void atp_complete(struct urb *urb)
+/* Check URB status and for correct length of data package */
+
+#define ATP_URB_STATUS_SUCCESS         0
+#define ATP_URB_STATUS_ERROR           1
+#define ATP_URB_STATUS_ERROR_FATAL     2
+
+static int atp_status_check(struct urb *urb)
 {
-       int x, y, x_z, y_z, x_f, y_f;
-       int retval, i, j;
-       int key;
        struct atp *dev = urb->context;
 
        switch (urb->status) {
@@ -351,11 +368,12 @@ static void atp_complete(struct urb *urb)
                /* This urb is terminated, clean up */
                dbg("atp_complete: urb shutting down with status: %d",
                    urb->status);
-               return;
+               return ATP_URB_STATUS_ERROR_FATAL;
+
        default:
                dbg("atp_complete: nonzero urb status received: %d",
                    urb->status);
-               goto exit;
+               return ATP_URB_STATUS_ERROR;
        }
 
        /* drop incomplete datasets */
@@ -363,30 +381,33 @@ static void atp_complete(struct urb *urb)
                dprintk("appletouch: incomplete data package"
                        " (first byte: %d, length: %d).\n",
                        dev->data[0], dev->urb->actual_length);
-               goto exit;
+               return ATP_URB_STATUS_ERROR;
        }
 
-       /* reorder the sensors values */
-       if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
-               memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
+       return ATP_URB_STATUS_SUCCESS;
+}
 
-               /*
-                * The values are laid out like this:
-                * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
-                * '-' is an unused value.
-                */
+/*
+ * USB interrupt callback functions
+ */
 
-               /* read X values */
-               for (i = 0, j = 19; i < 20; i += 2, j += 3) {
-                       dev->xy_cur[i] = dev->data[j + 1];
-                       dev->xy_cur[i + 1] = dev->data[j + 2];
-               }
-               /* read Y values */
-               for (i = 0, j = 1; i < 9; i += 2, j += 3) {
-                       dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
-                       dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
-               }
-       } else if (dev->type == ATP_GEYSER2) {
+/* Interrupt function for older touchpads: FOUNTAIN/GEYSER1/GEYSER2 */
+
+static void atp_complete_geyser_1_2(struct urb *urb)
+{
+       int x, y, x_z, y_z, x_f, y_f;
+       int retval, i, j;
+       int key;
+       struct atp *dev = urb->context;
+       int status = atp_status_check(urb);
+
+       if (status == ATP_URB_STATUS_ERROR_FATAL)
+               return;
+       else if (status == ATP_URB_STATUS_ERROR)
+               goto exit;
+
+       /* reorder the sensors values */
+       if (dev->type == ATP_GEYSER2) {
                memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 
                /*
@@ -427,34 +448,40 @@ static void atp_complete(struct urb *urb)
                /* first sample */
                dev->valid = true;
                dev->x_old = dev->y_old = -1;
+
+               /* Store first sample */
                memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
 
-               if (dev->size_detect_done ||
-                   dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */
-                       goto exit;
+               /* Perform size detection, if not done already */
+               if (!dev->size_detect_done) {
+
+                       /* 17" Powerbooks have extra X sensors */
+                       for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
+                            i < ATP_XSENSORS; i++) {
+                               if (!dev->xy_cur[i])
+                                       continue;
+
+                               printk(KERN_INFO
+                                       "appletouch: 17\" model detected.\n");
+
+                               if (dev->type == ATP_GEYSER2)
+                                       input_set_abs_params(dev->input, ABS_X,
+                                                            0,
+                                                            (20 - 1) *
+                                                            ATP_XFACT - 1,
+                                                            ATP_FUZZ, 0);
+                               else
+                                       input_set_abs_params(dev->input, ABS_X,
+                                                            0,
+                                                            (26 - 1) *
+                                                            ATP_XFACT - 1,
+                                                            ATP_FUZZ, 0);
+                               break;
+                       }
 
-               /* 17" Powerbooks have extra X sensors */
-               for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
-                    i < ATP_XSENSORS; i++) {
-                       if (!dev->xy_cur[i])
-                               continue;
-
-                       printk(KERN_INFO "appletouch: 17\" model detected.\n");
-                       if (dev->type == ATP_GEYSER2)
-                               input_set_abs_params(dev->input, ABS_X, 0,
-                                                    (20 - 1) *
-                                                    ATP_XFACT - 1,
-                                                    ATP_FUZZ, 0);
-                       else
-                               input_set_abs_params(dev->input, ABS_X, 0,
-                                                    (ATP_XSENSORS - 1) *
-                                                    ATP_XFACT - 1,
-                                                    ATP_FUZZ, 0);
-                       break;
+                       dev->size_detect_done = 1;
+                       goto exit;
                }
-
-               dev->size_detect_done = 1;
-               goto exit;
        }
 
        for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
@@ -475,7 +502,118 @@ static void atp_complete(struct urb *urb)
                              ATP_XFACT, &x_z, &x_f);
        y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
                              ATP_YFACT, &y_z, &y_f);
-       key = dev->data[dev->datalen - 1] & 1;
+       key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
+
+       if (x && y) {
+               if (dev->x_old != -1) {
+                       x = (dev->x_old * 3 + x) >> 2;
+                       y = (dev->y_old * 3 + y) >> 2;
+                       dev->x_old = x;
+                       dev->y_old = y;
+
+                       if (debug > 1)
+                               printk(KERN_DEBUG "appletouch: "
+                                       "X: %3d Y: %3d Xz: %3d Yz: %3d\n",
+                                       x, y, x_z, y_z);
+
+                       input_report_key(dev->input, BTN_TOUCH, 1);
+                       input_report_abs(dev->input, ABS_X, x);
+                       input_report_abs(dev->input, ABS_Y, y);
+                       input_report_abs(dev->input, ABS_PRESSURE,
+                                        min(ATP_PRESSURE, x_z + y_z));
+                       atp_report_fingers(dev->input, max(x_f, y_f));
+               }
+               dev->x_old = x;
+               dev->y_old = y;
+
+       } else if (!x && !y) {
+
+               dev->x_old = dev->y_old = -1;
+               input_report_key(dev->input, BTN_TOUCH, 0);
+               input_report_abs(dev->input, ABS_PRESSURE, 0);
+               atp_report_fingers(dev->input, 0);
+
+               /* reset the accumulator on release */
+               memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
+       }
+
+       input_report_key(dev->input, BTN_LEFT, key);
+       input_sync(dev->input);
+
+ exit:
+       retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
+       if (retval)
+               err("atp_complete: usb_submit_urb failed with result %d",
+                   retval);
+}
+
+/* Interrupt function for older touchpads: GEYSER3/GEYSER4 */
+
+static void atp_complete_geyser_3_4(struct urb *urb)
+{
+       int x, y, x_z, y_z, x_f, y_f;
+       int retval, i, j;
+       int key;
+       struct atp *dev = urb->context;
+       int status = atp_status_check(urb);
+
+       if (status == ATP_URB_STATUS_ERROR_FATAL)
+               return;
+       else if (status == ATP_URB_STATUS_ERROR)
+               goto exit;
+
+       /* Reorder the sensors values:
+        *
+        * The values are laid out like this:
+        * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
+        * '-' is an unused value.
+        */
+
+       /* read X values */
+       for (i = 0, j = 19; i < 20; i += 2, j += 3) {
+               dev->xy_cur[i] = dev->data[j + 1];
+               dev->xy_cur[i + 1] = dev->data[j + 2];
+       }
+       /* read Y values */
+       for (i = 0, j = 1; i < 9; i += 2, j += 3) {
+               dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
+               dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
+       }
+
+       dbg_dump("sample", dev->xy_cur);
+
+       /* Just update the base values (i.e. touchpad in untouched state) */
+       if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) {
+
+               dprintk(KERN_DEBUG "appletouch: updated base values\n");
+
+               memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
+               goto exit;
+       }
+
+       for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
+               /* calculate the change */
+               dev->xy_acc[i] = dev->xy_cur[i] - dev->xy_old[i];
+
+               /* this is a round-robin value, so couple with that */
+               if (dev->xy_acc[i] > 127)
+                       dev->xy_acc[i] -= 256;
+
+               if (dev->xy_acc[i] < -127)
+                       dev->xy_acc[i] += 256;
+
+               /* prevent down drifting */
+               if (dev->xy_acc[i] < 0)
+                       dev->xy_acc[i] = 0;
+       }
+
+       dbg_dump("accumulator", dev->xy_acc);
+
+       x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
+                             ATP_XFACT, &x_z, &x_f);
+       y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
+                             ATP_YFACT, &y_z, &y_f);
+       key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
 
        if (x && y) {
                if (dev->x_old != -1) {
@@ -514,28 +652,27 @@ static void atp_complete(struct urb *urb)
        input_sync(dev->input);
 
        /*
-        * Many Geysers will continue to send packets continually after
+        * Geysers 3/4 will continue to send packets continually after
         * the first touch unless reinitialised. Do so if it's been
         * idle for a while in order to avoid waking the kernel up
-        * several hundred times a second. Re-initialization does not
-        * work on Fountain touchpads.
+        * several hundred times a second.
         */
-       if (dev->type != ATP_FOUNTAIN) {
-               /*
-                * Button must not be pressed when entering suspend,
-                * otherwise we will never release the button.
-                */
-               if (!x && !y && !key) {
-                       dev->idlecount++;
-                       if (dev->idlecount == 10) {
-                               dev->valid = false;
-                               schedule_work(&dev->work);
-                               /* Don't resubmit urb here, wait for reinit */
-                               return;
-                       }
-               } else
+
+       /*
+        * Button must not be pressed when entering suspend,
+        * otherwise we will never release the button.
+        */
+       if (!x && !y && !key) {
+               dev->idlecount++;
+               if (dev->idlecount == 10) {
+                       dev->x_old = dev->y_old = -1;
                        dev->idlecount = 0;
-       }
+                       schedule_work(&dev->work);
+                       /* Don't resubmit urb here, wait for reinit */
+                       return;
+               }
+       } else
+               dev->idlecount = 0;
 
  exit:
        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -632,9 +769,19 @@ static int atp_probe(struct usb_interface *iface,
        if (!dev->data)
                goto err_free_urb;
 
-       usb_fill_int_urb(dev->urb, udev,
-                        usb_rcvintpipe(udev, int_in_endpointAddr),
-                        dev->data, dev->datalen, atp_complete, dev, 1);
+       /* Select the USB complete (callback) function */
+       if (dev->type == ATP_FOUNTAIN ||
+           dev->type == ATP_GEYSER1 ||
+           dev->type == ATP_GEYSER2)
+               usb_fill_int_urb(dev->urb, udev,
+                                usb_rcvintpipe(udev, int_in_endpointAddr),
+                                dev->data, dev->datalen,
+                                atp_complete_geyser_1_2, dev, 1);
+       else
+               usb_fill_int_urb(dev->urb, udev,
+                                usb_rcvintpipe(udev, int_in_endpointAddr),
+                                dev->data, dev->datalen,
+                                atp_complete_geyser_3_4, dev, 1);
 
        error = atp_handle_geyser(dev);
        if (error)
@@ -751,8 +898,6 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
        struct atp *dev = usb_get_intfdata(iface);
 
        usb_kill_urb(dev->urb);
-       dev->valid = false;
-
        return 0;
 }
 
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
new file mode 100644 (file)
index 0000000..e82d342
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
+ *
+ * Copyright (c) 2006-2008 One Laptop Per Child
+ * Authors:
+ *   Zephaniah E. Hull
+ *   Andres Salomon <dilinger@debian.org>
+ *
+ * This driver is partly based on the ALPS driver, which is:
+ *
+ * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
+ * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
+ * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
+ *
+ * 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.
+ */
+
+/*
+ * The spec from ALPS is available from
+ * <http://wiki.laptop.org/go/Touch_Pad/Tablet>.  It refers to this
+ * device as HGPK (Hybrid GS, PT, and Keymatrix).
+ *
+ * The earliest versions of the device had simultaneous reporting; that
+ * was removed.  After that, the device used the Advanced Mode GS/PT streaming
+ * stuff.  That turned out to be too buggy to support, so we've finally
+ * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad).
+ */
+
+#define DEBUG
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/libps2.h>
+#include <linux/delay.h>
+#include <asm/olpc.h>
+
+#include "psmouse.h"
+#include "hgpk.h"
+
+static int tpdebug;
+module_param(tpdebug, int, 0644);
+MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
+
+static int recalib_delta = 100;
+module_param(recalib_delta, int, 0644);
+MODULE_PARM_DESC(recalib_delta,
+       "packets containing a delta this large will cause a recalibration.");
+
+/*
+ * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
+ * above the pad and still have it send packets.  This causes a jump cursor
+ * when one places their finger on the pad.  We can probably detect the
+ * jump as we see a large deltas (>= 100px).  In mouse mode, I've been
+ * unable to even come close to 100px deltas during normal usage, so I think
+ * this threshold is safe.  If a large delta occurs, trigger a recalibration.
+ */
+static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)
+{
+       struct hgpk_data *priv = psmouse->private;
+
+       if (abs(x) > recalib_delta || abs(y) > recalib_delta) {
+               hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n",
+                               recalib_delta, x, y);
+               /* My car gets forty rods to the hogshead and that's the
+                * way I likes it! */
+               psmouse_queue_work(psmouse, &priv->recalib_wq,
+                               msecs_to_jiffies(1000));
+       }
+}
+
+/*
+ * We have no idea why this particular hardware bug occurs.  The touchpad
+ * will randomly start spewing packets without anything touching the
+ * pad.  This wouldn't necessarily be bad, but it's indicative of a
+ * severely miscalibrated pad; attempting to use the touchpad while it's
+ * spewing means the cursor will jump all over the place, and act "drunk".
+ *
+ * The packets that are spewed tend to all have deltas between -2 and 2, and
+ * the cursor will move around without really going very far.  It will
+ * tend to end up in the same location; if we tally up the changes over
+ * 100 packets, we end up w/ a final delta of close to 0.  This happens
+ * pretty regularly when the touchpad is spewing, and is pretty hard to
+ * manually trigger (at least for *my* fingers).  So, it makes a perfect
+ * scheme for detecting spews.
+ */
+static void hgpk_spewing_hack(struct psmouse *psmouse,
+                             int l, int r, int x, int y)
+{
+       struct hgpk_data *priv = psmouse->private;
+
+       /* ignore button press packets; many in a row could trigger
+        * a false-positive! */
+       if (l || r)
+               return;
+
+       priv->x_tally += x;
+       priv->y_tally += y;
+
+       if (++priv->count > 100) {
+               if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
+                       hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",
+                                priv->x_tally, priv->y_tally);
+                       psmouse_queue_work(psmouse, &priv->recalib_wq,
+                                          msecs_to_jiffies(1000));
+               }
+               /* reset every 100 packets */
+               priv->count = 0;
+               priv->x_tally = 0;
+               priv->y_tally = 0;
+       }
+}
+
+/*
+ * HGPK Mouse Mode format (standard mouse format, sans middle button)
+ *
+ * byte 0:     y-over  x-over  y-neg   x-neg   1       0       swr     swl
+ * byte 1:     x7      x6      x5      x4      x3      x2      x1      x0
+ * byte 2:     y7      y6      y5      y4      y3      y2      y1      y0
+ *
+ * swr/swl are the left/right buttons.
+ * x-neg/y-neg are the x and y delta negative bits
+ * x-over/y-over are the x and y overflow bits
+ */
+static int hgpk_validate_byte(unsigned char *packet)
+{
+       return (packet[0] & 0x0C) == 0x08;
+}
+
+static void hgpk_process_packet(struct psmouse *psmouse)
+{
+       struct input_dev *dev = psmouse->dev;
+       unsigned char *packet = psmouse->packet;
+       int x, y, left, right;
+
+       left = packet[0] & 1;
+       right = (packet[0] >> 1) & 1;
+
+       x = packet[1] - ((packet[0] << 4) & 0x100);
+       y = ((packet[0] << 3) & 0x100) - packet[2];
+
+       hgpk_jumpy_hack(psmouse, x, y);
+       hgpk_spewing_hack(psmouse, left, right, x, y);
+
+       if (tpdebug)
+               hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);
+
+       input_report_key(dev, BTN_LEFT, left);
+       input_report_key(dev, BTN_RIGHT, right);
+
+       input_report_rel(dev, REL_X, x);
+       input_report_rel(dev, REL_Y, y);
+
+       input_sync(dev);
+}
+
+static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
+{
+       struct hgpk_data *priv = psmouse->private;
+
+       if (hgpk_validate_byte(psmouse->packet)) {
+               hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",
+                               __func__, psmouse->pktcnt, psmouse->packet[0],
+                               psmouse->packet[1], psmouse->packet[2]);
+               return PSMOUSE_BAD_DATA;
+       }
+
+       if (psmouse->pktcnt >= psmouse->pktsize) {
+               hgpk_process_packet(psmouse);
+               return PSMOUSE_FULL_PACKET;
+       }
+
+       if (priv->recalib_window) {
+               if (time_before(jiffies, priv->recalib_window)) {
+                       /*
+                        * ugh, got a packet inside our recalibration
+                        * window, schedule another recalibration.
+                        */
+                       hgpk_dbg(psmouse,
+                                "packet inside calibration window, "
+                                "queueing another recalibration\n");
+                       psmouse_queue_work(psmouse, &priv->recalib_wq,
+                                       msecs_to_jiffies(1000));
+               }
+               priv->recalib_window = 0;
+       }
+
+       return PSMOUSE_GOOD_DATA;
+}
+
+static int hgpk_force_recalibrate(struct psmouse *psmouse)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       struct hgpk_data *priv = psmouse->private;
+
+       /* C-series touchpads added the recalibrate command */
+       if (psmouse->model < HGPK_MODEL_C)
+               return 0;
+
+       /* we don't want to race with the irq handler, nor with resyncs */
+       psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+       /* start by resetting the device */
+       psmouse_reset(psmouse);
+
+       /* send the recalibrate request */
+       if (ps2_command(ps2dev, NULL, 0xf5) ||
+           ps2_command(ps2dev, NULL, 0xf5) ||
+           ps2_command(ps2dev, NULL, 0xe6) ||
+           ps2_command(ps2dev, NULL, 0xf5)) {
+               return -1;
+       }
+
+       /* according to ALPS, 150mS is required for recalibration */
+       msleep(150);
+
+       /* XXX: If a finger is down during this delay, recalibration will
+        * detect capacitance incorrectly.  This is a hardware bug, and
+        * we don't have a good way to deal with it.  The 2s window stuff
+        * (below) is our best option for now.
+        */
+
+       if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+               return -1;
+
+       psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+
+       /* After we recalibrate, we shouldn't get any packets for 2s.  If
+        * we do, it's likely that someone's finger was on the touchpad.
+        * If someone's finger *was* on the touchpad, it's probably
+        * miscalibrated.  So, we should schedule another recalibration
+        */
+       priv->recalib_window = jiffies +  msecs_to_jiffies(2000);
+
+       return 0;
+}
+
+/*
+ * This kills power to the touchpad; according to ALPS, current consumption
+ * goes down to 50uA after running this.  To turn power back on, we drive
+ * MS-DAT low.
+ */
+static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       int timeo;
+
+       /* Added on D-series touchpads */
+       if (psmouse->model < HGPK_MODEL_D)
+               return 0;
+
+       if (enable) {
+               psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+               /*
+                * Sending a byte will drive MS-DAT low; this will wake up
+                * the controller.  Once we get an ACK back from it, it
+                * means we can continue with the touchpad re-init.  ALPS
+                * tells us that 1s should be long enough, so set that as
+                * the upper bound.
+                */
+               for (timeo = 20; timeo > 0; timeo--) {
+                       if (!ps2_sendbyte(&psmouse->ps2dev,
+                                       PSMOUSE_CMD_DISABLE, 20))
+                               break;
+                       msleep(50);
+               }
+
+               psmouse_reset(psmouse);
+
+               /* should be all set, enable the touchpad */
+               ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+               psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+
+       } else {
+               hgpk_dbg(psmouse, "Powering off touchpad.\n");
+               psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+
+               if (ps2_command(ps2dev, NULL, 0xec) ||
+                   ps2_command(ps2dev, NULL, 0xec) ||
+                   ps2_command(ps2dev, NULL, 0xea)) {
+                       return -1;
+               }
+
+               /* probably won't see an ACK, the touchpad will be off */
+               ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
+       }
+
+       return 0;
+}
+
+static int hgpk_poll(struct psmouse *psmouse)
+{
+       /* We can't poll, so always return failure. */
+       return -1;
+}
+
+static int hgpk_reconnect(struct psmouse *psmouse)
+{
+       /* During suspend/resume the ps2 rails remain powered.  We don't want
+        * to do a reset because it's flush data out of buffers; however,
+        * earlier prototypes (B1) had some brokenness that required a reset. */
+       if (olpc_board_at_least(olpc_board(0xb2)))
+               if (psmouse->ps2dev.serio->dev.power.power_state.event !=
+                               PM_EVENT_ON)
+                       return 0;
+
+       psmouse_reset(psmouse);
+
+       return 0;
+}
+
+static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
+{
+       struct hgpk_data *priv = psmouse->private;
+
+       return sprintf(buf, "%d\n", priv->powered);
+}
+
+static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
+                               const char *buf, size_t count)
+{
+       struct hgpk_data *priv = psmouse->private;
+       unsigned long value;
+       int err;
+
+       err = strict_strtoul(buf, 10, &value);
+       if (err || value > 1)
+               return -EINVAL;
+
+       if (value != priv->powered) {
+               /*
+                * hgpk_toggle_power will deal w/ state so
+                * we're not racing w/ irq
+                */
+               err = hgpk_toggle_power(psmouse, value);
+               if (!err)
+                       priv->powered = value;
+       }
+
+       return err ? err : count;
+}
+
+__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
+                     hgpk_show_powered, hgpk_set_powered, 0);
+
+static void hgpk_disconnect(struct psmouse *psmouse)
+{
+       struct hgpk_data *priv = psmouse->private;
+
+       device_remove_file(&psmouse->ps2dev.serio->dev,
+                          &psmouse_attr_powered.dattr);
+       psmouse_reset(psmouse);
+       kfree(priv);
+}
+
+static void hgpk_recalib_work(struct work_struct *work)
+{
+       struct delayed_work *w = container_of(work, struct delayed_work, work);
+       struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
+       struct psmouse *psmouse = priv->psmouse;
+
+       hgpk_dbg(psmouse, "recalibrating touchpad..\n");
+
+       if (hgpk_force_recalibrate(psmouse))
+               hgpk_err(psmouse, "recalibration failed!\n");
+}
+
+static int hgpk_register(struct psmouse *psmouse)
+{
+       struct input_dev *dev = psmouse->dev;
+       int err;
+
+       /* unset the things that psmouse-base sets which we don't have */
+       __clear_bit(BTN_MIDDLE, dev->keybit);
+
+       /* set the things we do have */
+       __set_bit(EV_KEY, dev->evbit);
+       __set_bit(EV_REL, dev->evbit);
+
+       __set_bit(REL_X, dev->relbit);
+       __set_bit(REL_Y, dev->relbit);
+
+       __set_bit(BTN_LEFT, dev->keybit);
+       __set_bit(BTN_RIGHT, dev->keybit);
+
+       /* register handlers */
+       psmouse->protocol_handler = hgpk_process_byte;
+       psmouse->poll = hgpk_poll;
+       psmouse->disconnect = hgpk_disconnect;
+       psmouse->reconnect = hgpk_reconnect;
+       psmouse->pktsize = 3;
+
+       /* Disable the idle resync. */
+       psmouse->resync_time = 0;
+       /* Reset after a lot of bad bytes. */
+       psmouse->resetafter = 1024;
+
+       err = device_create_file(&psmouse->ps2dev.serio->dev,
+                                &psmouse_attr_powered.dattr);
+       if (err)
+               hgpk_err(psmouse, "Failed to create sysfs attribute\n");
+
+       return err;
+}
+
+int hgpk_init(struct psmouse *psmouse)
+{
+       struct hgpk_data *priv;
+       int err = -ENOMEM;
+
+       priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
+       if (!priv)
+               goto alloc_fail;
+
+       psmouse->private = priv;
+       priv->psmouse = psmouse;
+       priv->powered = 1;
+       INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
+
+       err = psmouse_reset(psmouse);
+       if (err)
+               goto init_fail;
+
+       err = hgpk_register(psmouse);
+       if (err)
+               goto init_fail;
+
+       return 0;
+
+init_fail:
+       kfree(priv);
+alloc_fail:
+       return err;
+}
+
+static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       unsigned char param[3];
+
+       /* E7, E7, E7, E9 gets us a 3 byte identifier */
+       if (ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
+           ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
+           ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
+           ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
+               return -EIO;
+       }
+
+       hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);
+
+       /* HGPK signature: 0x67, 0x00, 0x<model> */
+       if (param[0] != 0x67 || param[1] != 0x00)
+               return -ENODEV;
+
+       hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
+
+       return param[2];
+}
+
+int hgpk_detect(struct psmouse *psmouse, int set_properties)
+{
+       int version;
+
+       version = hgpk_get_model(psmouse);
+       if (version < 0)
+               return version;
+
+       if (set_properties) {
+               psmouse->vendor = "ALPS";
+               psmouse->name = "HGPK";
+               psmouse->model = version;
+       }
+
+       return 0;
+}
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
new file mode 100644 (file)
index 0000000..a4b2a96
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
+ */
+
+#ifndef _HGPK_H
+#define _HGPK_H
+
+enum hgpk_model_t {
+       HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
+       HGPK_MODEL_A = 0x14,    /* found on B1s, PT disabled in hardware */
+       HGPK_MODEL_B = 0x28,    /* B2s, has capacitance issues */
+       HGPK_MODEL_C = 0x3c,
+       HGPK_MODEL_D = 0x50,    /* C1, mass production */
+};
+
+struct hgpk_data {
+       struct psmouse *psmouse;
+       int powered;
+       int count, x_tally, y_tally;    /* hardware workaround stuff */
+       unsigned long recalib_window;
+       struct delayed_work recalib_wq;
+};
+
+#define hgpk_dbg(psmouse, format, arg...)              \
+       dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_err(psmouse, format, arg...)              \
+       dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_info(psmouse, format, arg...)             \
+       dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_warn(psmouse, format, arg...)             \
+       dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_notice(psmouse, format, arg...)           \
+       dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+
+#ifdef CONFIG_MOUSE_PS2_OLPC
+int hgpk_detect(struct psmouse *psmouse, int set_properties);
+int hgpk_init(struct psmouse *psmouse);
+#else
+static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
+{
+       return -ENODEV;
+}
+static inline int hgpk_init(struct psmouse *psmouse)
+{
+       return -ENODEV;
+}
+#endif
+
+#endif
index 0c5660d28caa18bafb5d3ab62a9219f3fc1c96ec..390f1dbb98a482d855154119fa45ff52f3ea6bca 100644 (file)
@@ -157,10 +157,8 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data,
 static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
 {
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        ps2pp_set_smartscroll(psmouse, value);
index f5a6be1d3c46325b2173ff00e2588a9de9ca5d81..126e977e199e00764d3f2ab32aafbd0e26fbe7e8 100644 (file)
@@ -25,6 +25,7 @@
 #include "synaptics.h"
 #include "logips2pp.h"
 #include "alps.h"
+#include "hgpk.h"
 #include "lifebook.h"
 #include "trackpoint.h"
 #include "touchkit_ps2.h"
@@ -201,6 +202,12 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
        return PSMOUSE_FULL_PACKET;
 }
 
+void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
+               unsigned long delay)
+{
+       queue_delayed_work(kpsmoused_wq, work, delay);
+}
+
 /*
  * __psmouse_set_state() sets new psmouse state and resets all flags.
  */
@@ -220,7 +227,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta
  * is not a concern.
  */
 
-static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
+void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
 {
        serio_pause_rx(psmouse->ps2dev.serio);
        __psmouse_set_state(psmouse, new_state);
@@ -305,7 +312,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
                       psmouse->name, psmouse->phys, psmouse->pktcnt);
                psmouse->badbyte = psmouse->packet[0];
                __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
-               queue_work(kpsmoused_wq, &psmouse->resync_work);
+               psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
                goto out;
        }
 
@@ -342,7 +349,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
            time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
                psmouse->badbyte = psmouse->packet[0];
                __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
-               queue_work(kpsmoused_wq, &psmouse->resync_work);
+               psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
                goto out;
        }
 
@@ -630,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
                }
        }
 
-       if (max_proto > PSMOUSE_IMEX) {
+/*
+ * Try OLPC HGPK touchpad.
+ */
+       if (max_proto > PSMOUSE_IMEX &&
+                       hgpk_detect(psmouse, set_properties) == 0) {
+               if (!set_properties || hgpk_init(psmouse) == 0)
+                       return PSMOUSE_HGPK;
+/*
+ * Init failed, try basic relative protocols
+ */
+               max_proto = PSMOUSE_IMEX;
+       }
 
+       if (max_proto > PSMOUSE_IMEX) {
                if (genius_detect(psmouse, set_properties) == 0)
                        return PSMOUSE_GENPS;
 
@@ -761,6 +780,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .alias          = "touchkit",
                .detect         = touchkit_ps2_detect,
        },
+#endif
+#ifdef CONFIG_MOUSE_PS2_OLPC
+       {
+               .type           = PSMOUSE_HGPK,
+               .name           = "OLPC HGPK",
+               .alias          = "hgpk",
+               .detect         = hgpk_detect,
+       },
 #endif
        {
                .type           = PSMOUSE_CORTRON,
@@ -935,7 +962,7 @@ static int psmouse_poll(struct psmouse *psmouse)
 static void psmouse_resync(struct work_struct *work)
 {
        struct psmouse *parent = NULL, *psmouse =
-               container_of(work, struct psmouse, resync_work);
+               container_of(work, struct psmouse, resync_work.work);
        struct serio *serio = psmouse->ps2dev.serio;
        psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
        int failed = 0, enabled = 0;
@@ -1194,7 +1221,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
                goto err_free;
 
        ps2_init(&psmouse->ps2dev, serio);
-       INIT_WORK(&psmouse->resync_work, psmouse_resync);
+       INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
        psmouse->dev = input_dev;
        snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
 
@@ -1395,25 +1422,29 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
 
        psmouse = serio_get_drvdata(serio);
 
-       if (psmouse->state == PSMOUSE_IGNORE) {
-               retval = -ENODEV;
-               goto out_unlock;
-       }
+       if (attr->protect) {
+               if (psmouse->state == PSMOUSE_IGNORE) {
+                       retval = -ENODEV;
+                       goto out_unlock;
+               }
 
-       if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
-               psmouse_deactivate(parent);
-       }
+               if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
+                       parent = serio_get_drvdata(serio->parent);
+                       psmouse_deactivate(parent);
+               }
 
-       psmouse_deactivate(psmouse);
+               psmouse_deactivate(psmouse);
+       }
 
        retval = attr->set(psmouse, attr->data, buf, count);
 
-       if (retval != -ENODEV)
-               psmouse_activate(psmouse);
+       if (attr->protect) {
+               if (retval != -ENODEV)
+                       psmouse_activate(psmouse);
 
-       if (parent)
-               psmouse_activate(parent);
+               if (parent)
+                       psmouse_activate(parent);
+       }
 
  out_unlock:
        mutex_unlock(&psmouse_mutex);
@@ -1433,10 +1464,8 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const
 {
        unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest)
+       if (strict_strtoul(buf, 10, &value))
                return -EINVAL;
 
        if ((unsigned int)value != value)
@@ -1549,10 +1578,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
 static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
 {
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest)
+       if (strict_strtoul(buf, 10, &value))
                return -EINVAL;
 
        psmouse->set_rate(psmouse, value);
@@ -1562,10 +1589,8 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const
 static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
 {
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest)
+       if (strict_strtoul(buf, 10, &value))
                return -EINVAL;
 
        psmouse->set_resolution(psmouse, value);
index 1317bdd8cc7c42c935fac9899c5bdcbda0a5a51b..8b608a1cdd12171135f3ca2ec0c7a6487728711a 100644 (file)
@@ -39,7 +39,7 @@ struct psmouse {
        void *private;
        struct input_dev *dev;
        struct ps2dev ps2dev;
-       struct work_struct resync_work;
+       struct delayed_work resync_work;
        char *vendor;
        char *name;
        unsigned char packet[8];
@@ -89,20 +89,24 @@ enum psmouse_type {
        PSMOUSE_TRACKPOINT,
        PSMOUSE_TOUCHKIT_PS2,
        PSMOUSE_CORTRON,
+       PSMOUSE_HGPK,
        PSMOUSE_AUTO            /* This one should always be last */
 };
 
+void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
+               unsigned long delay);
 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
 int psmouse_reset(struct psmouse *psmouse);
+void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
 void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
 
-
 struct psmouse_attribute {
        struct device_attribute dattr;
        void *data;
        ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
        ssize_t (*set)(struct psmouse *psmouse, void *data,
                        const char *buf, size_t count);
+       int protect;
 };
 #define to_psmouse_attr(a)     container_of((a), struct psmouse_attribute, dattr)
 
@@ -111,7 +115,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
 ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
                                const char *buf, size_t count);
 
-#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set)                  \
+#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect)      \
 static ssize_t _show(struct psmouse *, void *data, char *);                    \
 static ssize_t _set(struct psmouse *, void *data, const char *, size_t);       \
 static struct psmouse_attribute psmouse_attr_##_name = {                       \
@@ -126,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = {                   \
        .data   = _data,                                                        \
        .show   = _show,                                                        \
        .set    = _set,                                                         \
+       .protect = _protect,                                                    \
 }
 
+#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set)  \
+               __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
+
 #endif /* _PSMOUSE_H */
index 26b845fc186ab7557635d6eafe59c7970c3507cc..e68c814c43612f449d4b9976a1cc45fbb7445efd 100644 (file)
@@ -89,10 +89,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
        struct trackpoint_attr_data *attr = data;
        unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 255)
+       if (strict_strtoul(buf, 10, &value) || value > 255)
                return -EINVAL;
 
        *field = value;
@@ -117,10 +115,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
        struct trackpoint_attr_data *attr = data;
        unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        if (attr->inverted)
index f451c7351a9da1b0614e1e04412f65e07116a37c..847f4aad7ed560f2c5d9b91f8ba34079b6c99d7c 100644 (file)
@@ -67,7 +67,7 @@ static inline int i8042_platform_init(void)
  * On some platforms touching the i8042 data register region can do really
  * bad things. Because of this the region is always reserved on such boxes.
  */
-#if defined(CONFIG_PPC_MERGE)
+#if defined(CONFIG_PPC)
        if (check_legacy_ioport(I8042_DATA_REG))
                return -ENODEV;
 #endif
index 5aafe24984c598236efdd54dde31e8db9ec6cc60..a321aea2c7b5f4dad1a9822539d2b3abb7700dfc 100644 (file)
@@ -322,6 +322,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
                },
        },
+       {
+               .ident = "IBM 2656",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
+               },
+       },
        { }
 };
 
index c9397c8ee97e8ea44c4f0edc4a6172bd022178ac..470770c09260334fd79c664c2a484ed0384a9f93 100644 (file)
@@ -373,6 +373,12 @@ static struct serio_device_id serio_raw_serio_ids[] = {
                .id     = SERIO_ANY,
                .extra  = SERIO_ANY,
        },
+       {
+               .type   = SERIO_8042_XL,
+               .proto  = SERIO_ANY,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
        { 0 }
 };
 
index 8f037a1d44a63be7586b0ac5f6309522437b290b..e53c838f1866cb69ddc33d2b9def78430777529e 100644 (file)
@@ -1202,16 +1202,22 @@ static ssize_t
 store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       int x;
+       long x;
+
+       if (strict_strtol(buf, 10, &x)) {
+               size_t len = buf[count - 1] == '\n' ? count - 1 : count;
+
+               if (strncmp(buf, "disable", len))
+                       return -EINVAL;
 
-       if (strcmp(buf, "disable") == 0) {
                aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
        } else {
-               x = (int)simple_strtol(buf, NULL, 10);
-               if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) {
-                       aiptek->newSetting.xTilt = x;
-               }
+               if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX)
+                       return -EINVAL;
+
+               aiptek->newSetting.xTilt = x;
        }
+
        return count;
 }
 
@@ -1238,16 +1244,22 @@ static ssize_t
 store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
-       int y;
+       long y;
+
+       if (strict_strtol(buf, 10, &y)) {
+               size_t len = buf[count - 1] == '\n' ? count - 1 : count;
+
+               if (strncmp(buf, "disable", len))
+                       return -EINVAL;
 
-       if (strcmp(buf, "disable") == 0) {
                aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
        } else {
-               y = (int)simple_strtol(buf, NULL, 10);
-               if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) {
-                       aiptek->newSetting.yTilt = y;
-               }
+               if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX)
+                       return -EINVAL;
+
+               aiptek->newSetting.yTilt = y;
        }
+
        return count;
 }
 
@@ -1269,8 +1281,12 @@ static ssize_t
 store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       long j;
+
+       if (strict_strtol(buf, 10, &j))
+               return -EINVAL;
 
-       aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10);
+       aiptek->newSetting.jitterDelay = (int)j;
        return count;
 }
 
@@ -1294,8 +1310,12 @@ static ssize_t
 store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       long d;
 
-       aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10);
+       if (strict_strtol(buf, 10, &d))
+               return -EINVAL;
+
+       aiptek->newSetting.programmableDelay = (int)d;
        return count;
 }
 
@@ -1541,8 +1561,11 @@ static ssize_t
 store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct aiptek *aiptek = dev_get_drvdata(dev);
+       long w;
+
+       if (strict_strtol(buf, 10, &w)) return -EINVAL;
 
-       aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10);
+       aiptek->newSetting.wheel = (int)w;
        return count;
 }
 
index 8583c766d565201e224fb21abaedd6c9cb8cadb8..b9b7fc6ff1ebcc657370701e9dcc53d3ce20bfdb 100644 (file)
@@ -69,6 +69,17 @@ struct ts_event {
        int     ignore;
 };
 
+/*
+ * We allocate this separately to avoid cache line sharing issues when
+ * driver is used with DMA-based SPI controllers (like atmel_spi) on
+ * systems where main memory is not DMA-coherent (most non-x86 boards).
+ */
+struct ads7846_packet {
+       u8                      read_x, read_y, read_z1, read_z2, pwrdown;
+       u16                     dummy;          /* for the pwrdown read */
+       struct ts_event         tc;
+};
+
 struct ads7846 {
        struct input_dev        *input;
        char                    phys[32];
@@ -86,9 +97,7 @@ struct ads7846 {
        u16                     x_plate_ohms;
        u16                     pressure_max;
 
-       u8                      read_x, read_y, read_z1, read_z2, pwrdown;
-       u16                     dummy;          /* for the pwrdown read */
-       struct ts_event         tc;
+       struct ads7846_packet   *packet;
 
        struct spi_transfer     xfer[18];
        struct spi_message      msg[5];
@@ -463,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev,
                                     const char *buf, size_t count)
 {
        struct ads7846 *ts = dev_get_drvdata(dev);
-       char *endp;
-       int i;
+       long i;
+
+       if (strict_strtoul(buf, 10, &i))
+               return -EINVAL;
 
-       i = simple_strtoul(buf, &endp, 10);
        spin_lock_irq(&ts->lock);
 
        if (i)
@@ -512,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts)
 static void ads7846_rx(void *ads)
 {
        struct ads7846          *ts = ads;
+       struct ads7846_packet   *packet = ts->packet;
        unsigned                Rt;
        u16                     x, y, z1, z2;
 
        /* ads7846_rx_val() did in-place conversion (including byteswap) from
         * on-the-wire format as part of debouncing to get stable readings.
         */
-       x = ts->tc.x;
-       y = ts->tc.y;
-       z1 = ts->tc.z1;
-       z2 = ts->tc.z2;
+       x = packet->tc.x;
+       y = packet->tc.y;
+       z1 = packet->tc.z1;
+       z2 = packet->tc.z2;
 
        /* range filtering */
        if (x == MAX_12BIT)
@@ -545,10 +556,10 @@ static void ads7846_rx(void *ads)
         * the maximum. Don't report it to user space, repeat at least
         * once more the measurement
         */
-       if (ts->tc.ignore || Rt > ts->pressure_max) {
+       if (packet->tc.ignore || Rt > ts->pressure_max) {
 #ifdef VERBOSE
                pr_debug("%s: ignored %d pressure %d\n",
-                       ts->spi->dev.bus_id, ts->tc.ignore, Rt);
+                       ts->spi->dev.bus_id, packet->tc.ignore, Rt);
 #endif
                hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
                              HRTIMER_MODE_REL);
@@ -641,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
 static void ads7846_rx_val(void *ads)
 {
        struct ads7846 *ts = ads;
+       struct ads7846_packet *packet = ts->packet;
        struct spi_message *m;
        struct spi_transfer *t;
        int val;
@@ -660,7 +672,7 @@ static void ads7846_rx_val(void *ads)
        case ADS7846_FILTER_REPEAT:
                break;
        case ADS7846_FILTER_IGNORE:
-               ts->tc.ignore = 1;
+               packet->tc.ignore = 1;
                /* Last message will contain ads7846_rx() as the
                 * completion function.
                 */
@@ -668,7 +680,7 @@ static void ads7846_rx_val(void *ads)
                break;
        case ADS7846_FILTER_OK:
                *(u16 *)t->rx_buf = val;
-               ts->tc.ignore = 0;
+               packet->tc.ignore = 0;
                m = &ts->msg[++ts->msg_idx];
                break;
        default:
@@ -773,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
        /* we know the chip's in lowpower mode since we always
         * leave it that way after every request
         */
-
 }
 
 /* Must be called with ts->lock held */
@@ -849,6 +860,7 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
 static int __devinit ads7846_probe(struct spi_device *spi)
 {
        struct ads7846                  *ts;
+       struct ads7846_packet           *packet;
        struct input_dev                *input_dev;
        struct ads7846_platform_data    *pdata = spi->dev.platform_data;
        struct spi_message              *m;
@@ -884,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                return err;
 
        ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
+       packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
        input_dev = input_allocate_device();
-       if (!ts || !input_dev) {
+       if (!ts || !packet || !input_dev) {
                err = -ENOMEM;
                goto err_free_mem;
        }
 
        dev_set_drvdata(&spi->dev, ts);
 
+       ts->packet = packet;
        ts->spi = spi;
        ts->input = input_dev;
        ts->vref_mv = pdata->vref_mv;
@@ -963,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        spi_message_init(m);
 
        /* y- still on; turn on only y+ (and ADC) */
-       ts->read_y = READ_Y(vref);
-       x->tx_buf = &ts->read_y;
+       packet->read_y = READ_Y(vref);
+       x->tx_buf = &packet->read_y;
        x->len = 1;
        spi_message_add_tail(x, m);
 
        x++;
-       x->rx_buf = &ts->tc.y;
+       x->rx_buf = &packet->tc.y;
        x->len = 2;
        spi_message_add_tail(x, m);
 
@@ -981,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                x->delay_usecs = pdata->settle_delay_usecs;
 
                x++;
-               x->tx_buf = &ts->read_y;
+               x->tx_buf = &packet->read_y;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.y;
+               x->rx_buf = &packet->tc.y;
                x->len = 2;
                spi_message_add_tail(x, m);
        }
@@ -999,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
 
        /* turn y- off, x+ on, then leave in lowpower */
        x++;
-       ts->read_x = READ_X(vref);
-       x->tx_buf = &ts->read_x;
+       packet->read_x = READ_X(vref);
+       x->tx_buf = &packet->read_x;
        x->len = 1;
        spi_message_add_tail(x, m);
 
        x++;
-       x->rx_buf = &ts->tc.x;
+       x->rx_buf = &packet->tc.x;
        x->len = 2;
        spi_message_add_tail(x, m);
 
@@ -1014,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                x->delay_usecs = pdata->settle_delay_usecs;
 
                x++;
-               x->tx_buf = &ts->read_x;
+               x->tx_buf = &packet->read_x;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.x;
+               x->rx_buf = &packet->tc.x;
                x->len = 2;
                spi_message_add_tail(x, m);
        }
@@ -1033,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                spi_message_init(m);
 
                x++;
-               ts->read_z1 = READ_Z1(vref);
-               x->tx_buf = &ts->read_z1;
+               packet->read_z1 = READ_Z1(vref);
+               x->tx_buf = &packet->read_z1;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.z1;
+               x->rx_buf = &packet->tc.z1;
                x->len = 2;
                spi_message_add_tail(x, m);
 
@@ -1048,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                        x->delay_usecs = pdata->settle_delay_usecs;
 
                        x++;
-                       x->tx_buf = &ts->read_z1;
+                       x->tx_buf = &packet->read_z1;
                        x->len = 1;
                        spi_message_add_tail(x, m);
 
                        x++;
-                       x->rx_buf = &ts->tc.z1;
+                       x->rx_buf = &packet->tc.z1;
                        x->len = 2;
                        spi_message_add_tail(x, m);
                }
@@ -1065,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                spi_message_init(m);
 
                x++;
-               ts->read_z2 = READ_Z2(vref);
-               x->tx_buf = &ts->read_z2;
+               packet->read_z2 = READ_Z2(vref);
+               x->tx_buf = &packet->read_z2;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.z2;
+               x->rx_buf = &packet->tc.z2;
                x->len = 2;
                spi_message_add_tail(x, m);
 
@@ -1080,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                        x->delay_usecs = pdata->settle_delay_usecs;
 
                        x++;
-                       x->tx_buf = &ts->read_z2;
+                       x->tx_buf = &packet->read_z2;
                        x->len = 1;
                        spi_message_add_tail(x, m);
 
                        x++;
-                       x->rx_buf = &ts->tc.z2;
+                       x->rx_buf = &packet->tc.z2;
                        x->len = 2;
                        spi_message_add_tail(x, m);
                }
@@ -1099,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        spi_message_init(m);
 
        x++;
-       ts->pwrdown = PWRDOWN;
-       x->tx_buf = &ts->pwrdown;
+       packet->pwrdown = PWRDOWN;
+       x->tx_buf = &packet->pwrdown;
        x->len = 1;
        spi_message_add_tail(x, m);
 
        x++;
-       x->rx_buf = &ts->dummy;
+       x->rx_buf = &packet->dummy;
        x->len = 2;
        CS_CHANGE(*x);
        spi_message_add_tail(x, m);
@@ -1158,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                ts->filter_cleanup(ts->filter_data);
  err_free_mem:
        input_free_device(input_dev);
+       kfree(packet);
        kfree(ts);
        return err;
 }
@@ -1183,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
        if (ts->filter_cleanup)
                ts->filter_cleanup(ts->filter_data);
 
+       kfree(ts->packet);
        kfree(ts);
 
        dev_dbg(&spi->dev, "unregistered touchscreen\n");
index eee126b19e8b53cc3a8949a3798df9cd13c6d402..a89a6a8f05e6c9631f7368fb2488e080490b6fe0 100644 (file)
@@ -91,6 +91,9 @@ struct atmel_tsadcc {
        char                    phys[32];
        struct clk              *clk;
        int                     irq;
+       unsigned int            prev_absx;
+       unsigned int            prev_absy;
+       unsigned char           bufferedmeasure;
 };
 
 static void __iomem            *tsc_base;
@@ -100,10 +103,9 @@ static void __iomem                *tsc_base;
 
 static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
 {
-       struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input;
+       struct atmel_tsadcc     *ts_dev = (struct atmel_tsadcc *)dev;
+       struct input_dev        *input_dev = ts_dev->input;
 
-       unsigned int absx;
-       unsigned int absy;
        unsigned int status;
        unsigned int reg;
 
@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
                atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
 
                input_report_key(input_dev, BTN_TOUCH, 0);
+               ts_dev->bufferedmeasure = 0;
                input_sync(input_dev);
 
        } else if (status & ATMEL_TSADCC_PENCNT) {
@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
        } else if (status & ATMEL_TSADCC_EOC(3)) {
                /* Conversion finished */
 
-               absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
-               absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
-
-               absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
-               absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
-
-               input_report_abs(input_dev, ABS_X, absx);
-               input_report_abs(input_dev, ABS_Y, absy);
-               input_report_key(input_dev, BTN_TOUCH, 1);
-               input_sync(input_dev);
+               if (ts_dev->bufferedmeasure) {
+                       /* Last measurement is always discarded, since it can
+                        * be erroneous.
+                        * Always report previous measurement */
+                       input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
+                       input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
+                       input_report_key(input_dev, BTN_TOUCH, 1);
+                       input_sync(input_dev);
+               } else
+                       ts_dev->bufferedmeasure = 1;
+
+               /* Now make new measurement */
+               ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
+               ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
+
+               ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
+               ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
        }
 
        return IRQ_HANDLED;
@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
        }
 
        ts_dev->input = input_dev;
+       ts_dev->bufferedmeasure = 0;
 
        snprintf(ts_dev->phys, sizeof(ts_dev->phys),
                 "%s/input0", pdev->dev.bus_id);
index 37a555f37306226ff0dae5495bfa45c733d297a2..ba648750a8d927db4a4cade7e2df61cca5348059 100644 (file)
@@ -3,8 +3,7 @@
  *                         Wolfson WM97xx AC97 Codecs.
  *
  * Copyright 2004, 2007 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  * Parts Copyright : Ian Molton <spyro@f2s.com>
  *                   Andrew Zabolotny <zap@homelink.ru>
  *
@@ -296,6 +295,6 @@ module_init(mainstone_wm97xx_init);
 module_exit(mainstone_wm97xx_exit);
 
 /* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
 MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
 MODULE_LICENSE("GPL");
index 372efbc694ffbf7ebe71e96decefd71060e6d7c8..6b5be742c27dac15fd5b11734b2759638b8046f0 100644 (file)
@@ -2,8 +2,7 @@
  * wm9705.c  --  Codec driver for Wolfson WM9705 AC97 Codec.
  *
  * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  * Parts Copyright : Ian Molton <spyro@f2s.com>
  *                   Andrew Zabolotny <zap@homelink.ru>
  *                   Russell King <rmk@arm.linux.org.uk>
@@ -347,6 +346,6 @@ struct wm97xx_codec_drv wm9705_codec = {
 EXPORT_SYMBOL_GPL(wm9705_codec);
 
 /* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
 MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
 MODULE_LICENSE("GPL");
index c8bb1e7335fcf8f9450c0be194cafc9f014d03fb..7490b05c356651cf8aa6e2d0e1ee1b1621096cd6 100644 (file)
@@ -2,8 +2,7 @@
  * wm9712.c  --  Codec driver for Wolfson WM9712 AC97 Codecs.
  *
  * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  * Parts Copyright : Ian Molton <spyro@f2s.com>
  *                   Andrew Zabolotny <zap@homelink.ru>
  *                   Russell King <rmk@arm.linux.org.uk>
@@ -462,6 +461,6 @@ struct wm97xx_codec_drv wm9712_codec = {
 EXPORT_SYMBOL_GPL(wm9712_codec);
 
 /* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
 MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
 MODULE_LICENSE("GPL");
index 781ee83547e68374eba1f253a016a26435135e27..238b5132712eef7b4986636b16ce78c070df15b0 100644 (file)
@@ -2,8 +2,7 @@
  * wm9713.c  --  Codec touch driver for Wolfson WM9713 AC97 Codec.
  *
  * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  * Parts Copyright : Ian Molton <spyro@f2s.com>
  *                   Andrew Zabolotny <zap@homelink.ru>
  *                   Russell King <rmk@arm.linux.org.uk>
@@ -476,6 +475,6 @@ struct wm97xx_codec_drv wm9713_codec = {
 EXPORT_SYMBOL_GPL(wm9713_codec);
 
 /* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
 MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
 MODULE_LICENSE("GPL");
index d589ab0e3adc41c0b75eb55c645937afdcdef843..d15aa11d705686adb89203e396577752d44c9cf3 100644 (file)
@@ -3,8 +3,7 @@
  *                    and WM9713 AC97 Codecs.
  *
  * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  * Parts Copyright : Ian Molton <spyro@f2s.com>
  *                   Andrew Zabolotny <zap@homelink.ru>
  *                   Russell King <rmk@arm.linux.org.uk>
@@ -824,6 +823,6 @@ module_init(wm97xx_init);
 module_exit(wm97xx_exit);
 
 /* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
 MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
 MODULE_LICENSE("GPL");
index 798d7f3e42efbcaad5e871b0590a6cc77933fbc1..1b5bf87c4cf4719cd66e75575d3b97250e368e06 100644 (file)
@@ -1553,8 +1553,7 @@ static int __init capi_init(void)
                return PTR_ERR(capi_class);
        }
 
-       device_create_drvdata(capi_class, NULL, MKDEV(capi_major, 0), NULL,
-                             "capi");
+       device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        if (capinc_tty_init() < 0) {
index 559a40861c39b2e8e8fd7531acb06dc00a20dde2..ee74ee7b2accab837fc43c0c8cda523795bed5ce 100644 (file)
@@ -103,8 +103,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
        int rc;
 
-       led_cdev->dev = device_create_drvdata(leds_class, parent, 0, led_cdev,
-                                             "%s", led_cdev->name);
+       led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
+                                     "%s", led_cdev->name);
        if (IS_ERR(led_cdev->dev))
                return PTR_ERR(led_cdev->dev);
 
index cae52485208aaf022bd57689dcf8a4b30173aa2e..23741cec45e3e43210fdbac7e11c6ecc9c4eb1d5 100644 (file)
@@ -862,8 +862,7 @@ adbdev_init(void)
        adb_dev_class = class_create(THIS_MODULE, "adb");
        if (IS_ERR(adb_dev_class))
                return;
-       device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL,
-                             "adb");
+       device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
 
        platform_device_register(&adb_pfdev);
        platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
index 268547dbfbd30ce2942b3b5d92c9bbfab793d4b7..f26c1f9a475b8d9cbad5f885016e50723b580cd5 100644 (file)
@@ -287,6 +287,8 @@ static int run(mddev_t *mddev)
        int i;
 
        conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL);
+       if (!conf)
+               return -ENOMEM;
 
        for (i=0; i<Modes; i++) {
                atomic_set(&conf->counters[i], 0);
index b9cbee688fae9e4d28c9d62f58780d39254e0e3d..190147c79e79fbbe9b0e2c0935aa7ac697464a1b 100644 (file)
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#include <linux/module.h>
-
-#include <linux/raid/md.h>
-#include <linux/slab.h>
 #include <linux/raid/linear.h>
 
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
-
 /*
  * find which device holds a particular offset 
  */
@@ -33,16 +25,15 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
 {
        dev_info_t *hash;
        linear_conf_t *conf = mddev_to_conf(mddev);
-       sector_t block = sector >> 1;
 
        /*
         * sector_div(a,b) returns the remainer and sets a to a/b
         */
-       block >>= conf->preshift;
-       (void)sector_div(block, conf->hash_spacing);
-       hash = conf->hash_table[block];
+       sector >>= conf->sector_shift;
+       (void)sector_div(sector, conf->spacing);
+       hash = conf->hash_table[sector];
 
-       while ((sector>>1) >= (hash->size + hash->offset))
+       while (sector >= hash->num_sectors + hash->start_sector)
                hash++;
        return hash;
 }
@@ -65,7 +56,7 @@ static int linear_mergeable_bvec(struct request_queue *q,
        sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
 
        dev0 = which_dev(mddev, sector);
-       maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1));
+       maxsectors = dev0->num_sectors - (sector - dev0->start_sector);
 
        if (maxsectors < bio_sectors)
                maxsectors = 0;
@@ -112,8 +103,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
        dev_info_t **table;
        mdk_rdev_t *rdev;
        int i, nb_zone, cnt;
-       sector_t min_spacing;
-       sector_t curr_offset;
+       sector_t min_sectors;
+       sector_t curr_sector;
        struct list_head *tmp;
 
        conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t),
@@ -145,7 +136,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                    mddev->queue->max_sectors > (PAGE_SIZE>>9))
                        blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
-               disk->size = rdev->size;
+               disk->num_sectors = rdev->size * 2;
                conf->array_sectors += rdev->size * 2;
 
                cnt++;
@@ -155,34 +146,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                goto out;
        }
 
-       min_spacing = conf->array_sectors / 2;
-       sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
+       min_sectors = conf->array_sectors;
+       sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *));
 
-       /* min_spacing is the minimum spacing that will fit the hash
+       /* min_sectors is the minimum spacing that will fit the hash
         * table in one PAGE.  This may be much smaller than needed.
         * We find the smallest non-terminal set of consecutive devices
-        * that is larger than min_spacing as use the size of that as
+        * that is larger than min_sectors and use the size of that as
         * the actual spacing
         */
-       conf->hash_spacing = conf->array_sectors / 2;
+       conf->spacing = conf->array_sectors;
        for (i=0; i < cnt-1 ; i++) {
-               sector_t sz = 0;
+               sector_t tmp = 0;
                int j;
-               for (j = i; j < cnt - 1 && sz < min_spacing; j++)
-                       sz += conf->disks[j].size;
-               if (sz >= min_spacing && sz < conf->hash_spacing)
-                       conf->hash_spacing = sz;
+               for (j = i; j < cnt - 1 && tmp < min_sectors; j++)
+                       tmp += conf->disks[j].num_sectors;
+               if (tmp >= min_sectors && tmp < conf->spacing)
+                       conf->spacing = tmp;
        }
 
-       /* hash_spacing may be too large for sector_div to work with,
+       /* spacing may be too large for sector_div to work with,
         * so we might need to pre-shift
         */
-       conf->preshift = 0;
+       conf->sector_shift = 0;
        if (sizeof(sector_t) > sizeof(u32)) {
-               sector_t space = conf->hash_spacing;
+               sector_t space = conf->spacing;
                while (space > (sector_t)(~(u32)0)) {
                        space >>= 1;
-                       conf->preshift++;
+                       conf->sector_shift++;
                }
        }
        /*
@@ -194,9 +185,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                unsigned round;
                unsigned long base;
 
-               sz = conf->array_sectors >> (conf->preshift + 1);
+               sz = conf->array_sectors >> conf->sector_shift;
                sz += 1; /* force round-up */
-               base = conf->hash_spacing >> conf->preshift;
+               base = conf->spacing >> conf->sector_shift;
                round = sector_div(sz, base);
                nb_zone = sz + (round ? 1 : 0);
        }
@@ -211,32 +202,31 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
         * Here we generate the linear hash table
         * First calculate the device offsets.
         */
-       conf->disks[0].offset = 0;
+       conf->disks[0].start_sector = 0;
        for (i = 1; i < raid_disks; i++)
-               conf->disks[i].offset =
-                       conf->disks[i-1].offset +
-                       conf->disks[i-1].size;
+               conf->disks[i].start_sector =
+                       conf->disks[i-1].start_sector +
+                       conf->disks[i-1].num_sectors;
 
        table = conf->hash_table;
-       curr_offset = 0;
        i = 0;
-       for (curr_offset = 0;
-            curr_offset < conf->array_sectors / 2;
-            curr_offset += conf->hash_spacing) {
+       for (curr_sector = 0;
+            curr_sector < conf->array_sectors;
+            curr_sector += conf->spacing) {
 
                while (i < raid_disks-1 &&
-                      curr_offset >= conf->disks[i+1].offset)
+                      curr_sector >= conf->disks[i+1].start_sector)
                        i++;
 
                *table ++ = conf->disks + i;
        }
 
-       if (conf->preshift) {
-               conf->hash_spacing >>= conf->preshift;
-               /* round hash_spacing up so that when we divide by it,
+       if (conf->sector_shift) {
+               conf->spacing >>= conf->sector_shift;
+               /* round spacing up so that when we divide by it,
                 * we err on the side of "too-low", which is safest.
                 */
-               conf->hash_spacing++;
+               conf->spacing++;
        }
 
        BUG_ON(table - conf->hash_table > nb_zone);
@@ -317,7 +307,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
        const int rw = bio_data_dir(bio);
        mddev_t *mddev = q->queuedata;
        dev_info_t *tmp_dev;
-       sector_t block;
        int cpu;
 
        if (unlikely(bio_barrier(bio))) {
@@ -332,29 +321,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
        part_stat_unlock();
 
        tmp_dev = which_dev(mddev, bio->bi_sector);
-       block = bio->bi_sector >> 1;
     
-       if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
-                    || block < tmp_dev->offset)) {
+       if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors +
+                                       tmp_dev->start_sector)
+                    || (bio->bi_sector <
+                        tmp_dev->start_sector))) {
                char b[BDEVNAME_SIZE];
 
-               printk("linear_make_request: Block %llu out of bounds on "
-                       "dev %s size %llu offset %llu\n",
-                       (unsigned long long)block,
+               printk("linear_make_request: Sector %llu out of bounds on "
+                       "dev %s: %llu sectors, offset %llu\n",
+                       (unsigned long long)bio->bi_sector,
                        bdevname(tmp_dev->rdev->bdev, b),
-                       (unsigned long long)tmp_dev->size,
-                       (unsigned long long)tmp_dev->offset);
+                       (unsigned long long)tmp_dev->num_sectors,
+                       (unsigned long long)tmp_dev->start_sector);
                bio_io_error(bio);
                return 0;
        }
        if (unlikely(bio->bi_sector + (bio->bi_size >> 9) >
-                    (tmp_dev->offset + tmp_dev->size)<<1)) {
+                    tmp_dev->start_sector + tmp_dev->num_sectors)) {
                /* This bio crosses a device boundary, so we have to
                 * split it.
                 */
                struct bio_pair *bp;
+
                bp = bio_split(bio,
-                              ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector);
+                              tmp_dev->start_sector + tmp_dev->num_sectors
+                              - bio->bi_sector);
+
                if (linear_make_request(q, &bp->bio1))
                        generic_make_request(&bp->bio1);
                if (linear_make_request(q, &bp->bio2))
@@ -364,7 +357,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
        }
                    
        bio->bi_bdev = tmp_dev->rdev->bdev;
-       bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset;
+       bio->bi_sector = bio->bi_sector - tmp_dev->start_sector
+               + tmp_dev->rdev->data_offset;
 
        return 1;
 }
@@ -372,29 +366,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
 static void linear_status (struct seq_file *seq, mddev_t *mddev)
 {
 
-#undef MD_DEBUG
-#ifdef MD_DEBUG
-       int j;
-       linear_conf_t *conf = mddev_to_conf(mddev);
-       sector_t s = 0;
-  
-       seq_printf(seq, "      ");
-       for (j = 0; j < mddev->raid_disks; j++)
-       {
-               char b[BDEVNAME_SIZE];
-               s += conf->smallest_size;
-               seq_printf(seq, "[%s",
-                          bdevname(conf->hash_table[j][0].rdev->bdev,b));
-
-               while (s > conf->hash_table[j][0].offset +
-                          conf->hash_table[j][0].size)
-                       seq_printf(seq, "/%s] ",
-                                  bdevname(conf->hash_table[j][1].rdev->bdev,b));
-               else
-                       seq_printf(seq, "] ");
-       }
-       seq_printf(seq, "\n");
-#endif
        seq_printf(seq, " %dk rounding", mddev->chunk_size/1024);
 }
 
index 0a3a4bdcd4afd55ad52fd08ecc3d99713bcb9a87..aaa3d465de4ece202bd3a18c1c605248ebd40ad7 100644 (file)
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/kthread.h>
-#include <linux/linkage.h>
 #include <linux/raid/md.h>
 #include <linux/raid/bitmap.h>
 #include <linux/sysctl.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/poll.h>
-#include <linux/mutex.h>
 #include <linux/ctype.h>
-#include <linux/freezer.h>
-
-#include <linux/init.h>
-
+#include <linux/hdreg.h>
+#include <linux/proc_fs.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
 #include <linux/file.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-#include <asm/unaligned.h>
+#include <linux/delay.h>
 
 #define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
 
 /* 63 partitions with the alternate major number (mdp) */
 #define MdpMinorShift 6
@@ -66,7 +56,7 @@
 
 
 #ifndef MODULE
-static void autostart_arrays (int part);
+static void autostart_arrays(int part);
 #endif
 
 static LIST_HEAD(pers_list);
@@ -212,7 +202,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
                )
 
 
-static int md_fail_request (struct request_queue *q, struct bio *bio)
+static int md_fail_request(struct request_queue *q, struct bio *bio)
 {
        bio_io_error(bio);
        return 0;
@@ -2106,8 +2096,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 
        if (strict_strtoull(buf, 10, &size) < 0)
                return -EINVAL;
-       if (size < my_mddev->size)
-               return -EINVAL;
        if (my_mddev->pers && rdev->raid_disk >= 0) {
                if (my_mddev->persistent) {
                        size = super_types[my_mddev->major_version].
@@ -2118,9 +2106,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                        size = (rdev->bdev->bd_inode->i_size >> 10);
                        size -= rdev->data_offset/2;
                }
-               if (size < my_mddev->size)
-                       return -EINVAL; /* component must fit device */
        }
+       if (size < my_mddev->size)
+               return -EINVAL; /* component must fit device */
 
        rdev->size = size;
        if (size > oldsize && my_mddev->external) {
@@ -2406,12 +2394,11 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
        int i;
        unsigned long msec;
        char buf[30];
-       char *e;
+
        /* remove a period, and count digits after it */
        if (len >= sizeof(buf))
                return -EINVAL;
-       strlcpy(buf, cbuf, len);
-       buf[len] = 0;
+       strlcpy(buf, cbuf, sizeof(buf));
        for (i=0; i<len; i++) {
                if (dot) {
                        if (isdigit(buf[i])) {
@@ -2424,8 +2411,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
                        buf[i] = 0;
                }
        }
-       msec = simple_strtoul(buf, &e, 10);
-       if (e == buf || (*e && *e != '\n'))
+       if (strict_strtoul(buf, 10, &msec) < 0)
                return -EINVAL;
        msec = (msec * 1000) / scale;
        if (msec == 0)
@@ -2727,9 +2713,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
                break;
        case read_auto:
                if (mddev->pers) {
-                       if (mddev->ro != 1)
+                       if (mddev->ro == 0)
                                err = do_md_stop(mddev, 1, 0);
-                       else
+                       else if (mddev->ro == 1)
                                err = restart_array(mddev);
                        if (err == 0) {
                                mddev->ro = 2;
@@ -2945,7 +2931,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
 {
        int major, minor;
        char *e;
-       if (!list_empty(&mddev->disks))
+       /* Changing the details of 'external' metadata is
+        * always permitted.  Otherwise there must be
+        * no devices attached to the array.
+        */
+       if (mddev->external && strncmp(buf, "external:", 9) == 0)
+               ;
+       else if (!list_empty(&mddev->disks))
                return -EBUSY;
 
        if (cmd_match(buf, "none")) {
@@ -3527,17 +3519,12 @@ static int do_md_run(mddev_t * mddev)
                        return -EINVAL;
                }
                /*
-                * chunk-size has to be a power of 2 and multiples of PAGE_SIZE
+                * chunk-size has to be a power of 2
                 */
                if ( (1 << ffz(~chunk_size)) != chunk_size) {
                        printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size);
                        return -EINVAL;
                }
-               if (chunk_size < PAGE_SIZE) {
-                       printk(KERN_ERR "too small chunk_size: %d < %ld\n",
-                               chunk_size, PAGE_SIZE);
-                       return -EINVAL;
-               }
 
                /* devices must have minimum size of one chunk */
                rdev_for_each(rdev, tmp, mddev) {
@@ -3555,12 +3542,10 @@ static int do_md_run(mddev_t * mddev)
                }
        }
 
-#ifdef CONFIG_KMOD
        if (mddev->level != LEVEL_NONE)
                request_module("md-level-%d", mddev->level);
        else if (mddev->clevel[0])
                request_module("md-%s", mddev->clevel);
-#endif
 
        /*
         * Drop all container device buffers, from now on
@@ -3971,10 +3956,10 @@ static void autorun_array(mddev_t *mddev)
        }
        printk("\n");
 
-       err = do_md_run (mddev);
+       err = do_md_run(mddev);
        if (err) {
                printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
-               do_md_stop (mddev, 0, 0);
+               do_md_stop(mddev, 0, 0);
        }
 }
 
@@ -4333,7 +4318,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
 
        if (!(info->state & (1<<MD_DISK_FAULTY))) {
                int err;
-               rdev = md_import_device (dev, -1, 0);
+               rdev = md_import_device(dev, -1, 0);
                if (IS_ERR(rdev)) {
                        printk(KERN_WARNING 
                                "md: error, md_import_device() returned %ld\n",
@@ -4415,7 +4400,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
                return -EINVAL;
        }
 
-       rdev = md_import_device (dev, -1, 0);
+       rdev = md_import_device(dev, -1, 0);
        if (IS_ERR(rdev)) {
                printk(KERN_WARNING 
                        "md: error, md_import_device() returned %ld\n",
@@ -4934,11 +4919,11 @@ static int md_ioctl(struct inode *inode, struct file *file,
                        goto done_unlock;
 
                case STOP_ARRAY:
-                       err = do_md_stop (mddev, 0, 1);
+                       err = do_md_stop(mddev, 0, 1);
                        goto done_unlock;
 
                case STOP_ARRAY_RO:
-                       err = do_md_stop (mddev, 1, 1);
+                       err = do_md_stop(mddev, 1, 1);
                        goto done_unlock;
 
        }
@@ -4987,7 +4972,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
                        goto done_unlock;
 
                case RUN_ARRAY:
-                       err = do_md_run (mddev);
+                       err = do_md_run(mddev);
                        goto done_unlock;
 
                case SET_BITMAP_FILE:
@@ -5425,11 +5410,11 @@ static int md_seq_show(struct seq_file *seq, void *v)
                        seq_printf(seq, " super non-persistent");
 
                if (mddev->pers) {
-                       mddev->pers->status (seq, mddev);
+                       mddev->pers->status(seq, mddev);
                        seq_printf(seq, "\n      ");
                        if (mddev->pers->sync_request) {
                                if (mddev->curr_resync > 2) {
-                                       status_resync (seq, mddev);
+                                       status_resync(seq, mddev);
                                        seq_printf(seq, "\n      ");
                                } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
                                        seq_printf(seq, "\tresync=DELAYED\n      ");
@@ -6260,7 +6245,7 @@ static int md_notify_reboot(struct notifier_block *this,
                                 * appears to still be in use.  Hence
                                 * the '100'.
                                 */
-                               do_md_stop (mddev, 1, 100);
+                               do_md_stop(mddev, 1, 100);
                                mddev_unlock(mddev);
                        }
                /*
@@ -6304,7 +6289,7 @@ static int __init md_init(void)
        raid_table_header = register_sysctl_table(raid_root_table);
 
        md_geninit();
-       return (0);
+       return 0;
 }
 
 
index 8bb8794129b372c9fdd065d961437c54e774d110..8744014b9d80cec8600fe95d9d10f5b9686b459f 100644 (file)
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
 #include <linux/raid/multipath.h>
-#include <linux/buffer_head.h>
-#include <asm/atomic.h>
-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
 
 #define MAX_WORK_PER_DISK 128
 
index 53508a8a981d70881eb130ef952033435e9b92f1..8ac6488ad0dc6c1a86463c4e732c1205a6cbb9a3 100644 (file)
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#include <linux/module.h>
 #include <linux/raid/raid0.h>
 
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
-
 static void raid0_unplug(struct request_queue *q)
 {
        mddev_t *mddev = q->queuedata;
index b9764429d856ead58ec0ffd51bc06da21e0891fc..9c788e2489b18934eadb62cac4d4b33b3c121620 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include "dm-bio-list.h"
+#include <linux/delay.h>
 #include <linux/raid/raid1.h>
 #include <linux/raid/bitmap.h>
 
index 8bdc9bfc288703aafbc8b20925f3d9b8e337fd54..da5129a24b18142d39595c86415bdef40612e353 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "dm-bio-list.h"
+#include <linux/delay.h>
 #include <linux/raid/raid10.h>
 #include <linux/raid/bitmap.h>
 
@@ -2028,8 +2029,9 @@ static int run(mddev_t *mddev)
        int nc, fc, fo;
        sector_t stride, size;
 
-       if (mddev->chunk_size == 0) {
-               printk(KERN_ERR "md/raid10: non-zero chunk size required.\n");
+       if (mddev->chunk_size < PAGE_SIZE) {
+               printk(KERN_ERR "md/raid10: chunk size must be "
+                      "at least PAGE_SIZE(%ld).\n", PAGE_SIZE);
                return -EINVAL;
        }
 
index ae16794bef209eeeae6cae8f074c6778674dd068..a36a7435edf51bd29cc32681cb8b211b29a9f8cb 100644 (file)
  * miss any bits.
  */
 
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/highmem.h>
-#include <linux/bitops.h>
 #include <linux/kthread.h>
-#include <asm/atomic.h>
 #include "raid6.h"
 
 #include <linux/raid/bitmap.h>
@@ -275,7 +270,7 @@ static int grow_buffers(struct stripe_head *sh, int num)
        return 0;
 }
 
-static void raid5_build_block (struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i);
 
 static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
 {
@@ -1151,7 +1146,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
        release_stripe(sh);
 }
 
-static void raid5_end_write_request (struct bio *bi, int error)
+static void raid5_end_write_request(struct bio *bi, int error)
 {
        struct stripe_head *sh = bi->bi_private;
        raid5_conf_t *conf = sh->raid_conf;
@@ -1183,7 +1178,7 @@ static void raid5_end_write_request (struct bio *bi, int error)
 
 static sector_t compute_blocknr(struct stripe_head *sh, int i);
        
-static void raid5_build_block (struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i)
 {
        struct r5dev *dev = &sh->dev[i];
 
@@ -1221,10 +1216,10 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
                }
                set_bit(Faulty, &rdev->flags);
-               printk (KERN_ALERT
-                       "raid5: Disk failure on %s, disabling device.\n"
-                       "raid5: Operation continuing on %d devices.\n",
-                       bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
+               printk(KERN_ALERT
+                      "raid5: Disk failure on %s, disabling device.\n"
+                      "raid5: Operation continuing on %d devices.\n",
+                      bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
        }
 }
 
@@ -1320,8 +1315,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
                        *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
                        break;
                default:
-                       printk (KERN_CRIT "raid6: unsupported algorithm %d\n",
-                               conf->algorithm);
+                       printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
+                              conf->algorithm);
                }
                break;
        }
@@ -1396,8 +1391,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
                        }
                        break;
                default:
-                       printk (KERN_CRIT "raid6: unsupported algorithm %d\n",
-                               conf->algorithm);
+                       printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
+                              conf->algorithm);
                }
                break;
        }
@@ -1405,7 +1400,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
        chunk_number = stripe * data_disks + i;
        r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
 
-       check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
+       check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
        if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
                printk(KERN_ERR "compute_blocknr: map not correct\n");
                return 0;
@@ -4012,6 +4007,13 @@ static int run(mddev_t *mddev)
                return -EIO;
        }
 
+       if (mddev->chunk_size < PAGE_SIZE) {
+               printk(KERN_ERR "md/raid5: chunk_size must be at least "
+                      "PAGE_SIZE but %d < %ld\n",
+                      mddev->chunk_size, PAGE_SIZE);
+               return -EINVAL;
+       }
+
        if (mddev->reshape_position != MaxSector) {
                /* Check that we can continue the reshape.
                 * Currently only disks can change, it must
@@ -4289,7 +4291,7 @@ static int stop(mddev_t *mddev)
 }
 
 #ifdef DEBUG
-static void print_sh (struct seq_file *seq, struct stripe_head *sh)
+static void print_sh(struct seq_file *seq, struct stripe_head *sh)
 {
        int i;
 
@@ -4305,7 +4307,7 @@ static void print_sh (struct seq_file *seq, struct stripe_head *sh)
        seq_printf(seq, "\n");
 }
 
-static void printall (struct seq_file *seq, raid5_conf_t *conf)
+static void printall(struct seq_file *seq, raid5_conf_t *conf)
 {
        struct stripe_head *sh;
        struct hlist_node *hn;
@@ -4323,7 +4325,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf)
 }
 #endif
 
-static void status (struct seq_file *seq, mddev_t *mddev)
+static void status(struct seq_file *seq, mddev_t *mddev)
 {
        raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
        int i;
index 31cbee71365f4d5ad969e4558b32147020b81173..98dcde88470e4c23b8fc204e46587be0243bfa32 100644 (file)
 /* Set to 1 to use kernel-wide empty_zero_page */
 #define RAID6_USE_EMPTY_ZERO_PAGE 0
 
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/mempool.h>
-#include <linux/list.h>
-#include <linux/vmalloc.h>
 #include <linux/raid/md.h>
 #include <linux/raid/raid5.h>
 
index e7132770a3bfdd656117890d11ff4ee6c9195302..665776d72a48c0456b712b25894760e60f48e4e8 100644 (file)
@@ -233,7 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        mutex_unlock(&dvbdev_register_lock);
 
-       clsdev = device_create_drvdata(dvb_class, adap->device,
+       clsdev = device_create(dvb_class, adap->device,
                               MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
                               NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
        if (IS_ERR(clsdev)) {
index c325e926de8a310f09eb15b3e0548a51d67e2e96..1798b779a25a10993e767a469ee860317016a992 100644 (file)
 #include <asm/io.h>
 #include <linux/mutex.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
 #include "cpia.h"
 
 static int video_nr = -1;
index b26b563a0b0a299a98bd7c4ef7114878fdb66d07..9e4f50639975308c0ca23ed446f1aa26d8e4f4df 100644 (file)
 
 #include <linux/workqueue.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
 #include "usbvision.h"
 
 static unsigned int core_debug;
index e10b256aeba4bc103675937df43ae71512336904..77aeb39b2750b1a34e660e3a733209e89da792af 100644 (file)
 
 #include <linux/workqueue.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
 #include "usbvision.h"
 #include "usbvision-cards.h"
 
index 79937d1031fc81283baf06abc62c5bc45a4c8409..928cb4037372e963f648c96656a65b9058baf98a 100644 (file)
 #include <asm/system.h>
 #include <asm/pgtable.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
 static unsigned int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable debug messages");
index 20c3be8617ea62eb583fd7827ad6c0c019de6d63..846763d7349e3ca73c3dc56f077da8bf98ca08c6 100644 (file)
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
 #include <linux/videodev2.h>
 
 MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
index 8ec57df1904f1e83d4940f395060459ecde38733..1efc5f3462c6ce8fa6e8edc45c45c7aceb445499 100644 (file)
 #include <linux/mm.h>
 #include <linux/time.h>
 #include <linux/version.h>
-
-#ifdef CONFIG_KMOD
 #include <linux/kmod.h>
-#endif
 
 #include <linux/i2c.h>
 #include <linux/i2c-algo-sgi.h>
@@ -4634,7 +4631,7 @@ static int __init vino_module_init(void)
        }
        vino_init_stage++;
 
-#if defined(CONFIG_KMOD) && defined(MODULE)
+#ifdef MODULE
        request_module("saa7191");
        request_module("indycam");
 #endif
index 11edf79f57be328a0f6a196f7d849776c3235a39..dcd45dbd82dcfa0424b900f78a495d85f5a3ec9e 100644 (file)
@@ -111,7 +111,7 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG;
 
 static unsigned int param_nv[24]; /* number of values per parameter */
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 module_param(ovmod_load, bool, 0644);
 #endif
 module_param(simcams, ushort, 0644);
@@ -144,7 +144,7 @@ module_param(debug, ushort, 0644);
 module_param(specific_debug, bool, 0644);
 #endif
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 MODULE_PARM_DESC(ovmod_load,
                 "\n<0|1> Automatic 'ovcamchip' module loading."
                 "\n0 disabled, 1 enabled."
index 2c2e39aa1efaf04d8747018369089bc44a0c3b8a..b0982dacfd0ac03fe71ac57e2740cc3599b55fd3 100644 (file)
@@ -5,7 +5,7 @@
 # In the future, some of these should be built conditionally.
 #
 
-i2o_core-y             += iop.o driver.o device.o debug.o pci.o exec-osm.o
+i2o_core-y             += iop.o driver.o device.o debug.o pci.o exec-osm.o memory.o
 i2o_bus-y              += bus-osm.o
 i2o_config-y           += config-osm.o
 obj-$(CONFIG_I2O)      += i2o_core.o
index 8774c670e668c55a4fe54bff02b014d0fcde89bc..54c2e9ae23e5e98c9b10849bab02364a338e3185 100644 (file)
@@ -467,7 +467,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
 
        res.virt = NULL;
 
-       if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL))
+       if (i2o_dma_alloc(dev, &res, reslen))
                return -ENOMEM;
 
        msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
index 6cbcc21de5182b2ce3e4087e3a022654eb7cb606..56faef1a1d55a3412d852ab9b56a805d0651627a 100644 (file)
@@ -388,8 +388,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
 
        dev = &c->pdev->dev;
 
-       if (i2o_dma_realloc
-           (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL))
+       if (i2o_dma_realloc(dev, &c->dlct,
+                                       le32_to_cpu(sb->expected_lct_size)))
                return -ENOMEM;
 
        msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
index 4238de98d4a68e9c9ab45b62d6d9fc0c6c73963b..a3fabdbe6ca6eb01efc616aee7df91cc4ae312c1 100644 (file)
@@ -260,7 +260,7 @@ static int i2o_cfg_swdl(unsigned long arg)
        if (IS_ERR(msg))
                return PTR_ERR(msg);
 
-       if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
+       if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
                i2o_msg_nop(c, msg);
                return -ENOMEM;
        }
@@ -339,7 +339,7 @@ static int i2o_cfg_swul(unsigned long arg)
        if (IS_ERR(msg))
                return PTR_ERR(msg);
 
-       if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
+       if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
                i2o_msg_nop(c, msg);
                return -ENOMEM;
        }
@@ -634,9 +634,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
                        sg_size = sg[i].flag_count & 0xffffff;
                        p = &(sg_list[sg_index]);
                        /* Allocate memory for the transfer */
-                       if (i2o_dma_alloc
-                           (&c->pdev->dev, p, sg_size,
-                            PCI_DMA_BIDIRECTIONAL)) {
+                       if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
                                printk(KERN_DEBUG
                                       "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
                                       c->name, sg_size, i, sg_count);
@@ -780,12 +778,11 @@ static int i2o_cfg_passthru(unsigned long arg)
        u32 size = 0;
        u32 reply_size = 0;
        u32 rcode = 0;
-       void *sg_list[SG_TABLESIZE];
+       struct i2o_dma sg_list[SG_TABLESIZE];
        u32 sg_offset = 0;
        u32 sg_count = 0;
        int sg_index = 0;
        u32 i = 0;
-       void *p = NULL;
        i2o_status_block *sb;
        struct i2o_message *msg;
        unsigned int iop;
@@ -842,6 +839,7 @@ static int i2o_cfg_passthru(unsigned long arg)
        memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
        if (sg_offset) {
                struct sg_simple_element *sg;
+               struct i2o_dma *p;
 
                if (sg_offset * 4 >= size) {
                        rcode = -EFAULT;
@@ -871,22 +869,22 @@ static int i2o_cfg_passthru(unsigned long arg)
                                goto sg_list_cleanup;
                        }
                        sg_size = sg[i].flag_count & 0xffffff;
+                       p = &(sg_list[sg_index]);
+                       if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
                        /* Allocate memory for the transfer */
-                       p = kmalloc(sg_size, GFP_KERNEL);
-                       if (!p) {
                                printk(KERN_DEBUG
                                       "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
                                       c->name, sg_size, i, sg_count);
                                rcode = -ENOMEM;
                                goto sg_list_cleanup;
                        }
-                       sg_list[sg_index++] = p;        // sglist indexed with input frame, not our internal frame.
+                       sg_index++;
                        /* Copy in the user's SG buffer if necessary */
                        if (sg[i].
                            flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
                                // TODO 64bit fix
                                if (copy_from_user
-                                   (p, (void __user *)sg[i].addr_bus,
+                                   (p->virt, (void __user *)sg[i].addr_bus,
                                     sg_size)) {
                                        printk(KERN_DEBUG
                                               "%s: Could not copy SG buf %d FROM user\n",
@@ -895,8 +893,7 @@ static int i2o_cfg_passthru(unsigned long arg)
                                        goto sg_list_cleanup;
                                }
                        }
-                       //TODO 64bit fix
-                       sg[i].addr_bus = virt_to_bus(p);
+                       sg[i].addr_bus = p->phys;
                }
        }
 
@@ -908,7 +905,7 @@ static int i2o_cfg_passthru(unsigned long arg)
        }
 
        if (sg_offset) {
-               u32 rmsg[128];
+               u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE];
                /* Copy back the Scatter Gather buffers back to user space */
                u32 j;
                // TODO 64bit fix
@@ -942,11 +939,11 @@ static int i2o_cfg_passthru(unsigned long arg)
                                sg_size = sg[j].flag_count & 0xffffff;
                                // TODO 64bit fix
                                if (copy_to_user
-                                   ((void __user *)sg[j].addr_bus, sg_list[j],
+                                   ((void __user *)sg[j].addr_bus, sg_list[j].virt,
                                     sg_size)) {
                                        printk(KERN_WARNING
                                               "%s: Could not copy %p TO user %x\n",
-                                              c->name, sg_list[j],
+                                              c->name, sg_list[j].virt,
                                               sg[j].addr_bus);
                                        rcode = -EFAULT;
                                        goto sg_list_cleanup;
@@ -973,7 +970,7 @@ sg_list_cleanup:
        }
 
        for (i = 0; i < sg_index; i++)
-               kfree(sg_list[i]);
+               i2o_dma_free(&c->pdev->dev, &sg_list[i]);
 
 cleanup:
        kfree(reply);
index da715e11c1b28cc493de7047e1772074c804e981..be2b5926d26c14b34bcbb40fd4db664f50618495 100644 (file)
@@ -1004,7 +1004,7 @@ static int i2o_hrt_get(struct i2o_controller *c)
 
                size = hrt->num_entries * hrt->entry_len << 2;
                if (size > c->hrt.len) {
-                       if (i2o_dma_realloc(dev, &c->hrt, size, GFP_KERNEL))
+                       if (i2o_dma_realloc(dev, &c->hrt, size))
                                return -ENOMEM;
                        else
                                hrt = c->hrt.virt;
diff --git a/drivers/message/i2o/memory.c b/drivers/message/i2o/memory.c
new file mode 100644 (file)
index 0000000..f5cc95c
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ *     Functions to handle I2O memory
+ *
+ *     Pulled from the inlines in i2o headers and uninlined
+ *
+ *
+ *     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/module.h>
+#include <linux/i2o.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "core.h"
+
+/* Protects our 32/64bit mask switching */
+static DEFINE_MUTEX(mem_lock);
+
+/**
+ *     i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
+ *     @c: I2O controller for which the calculation should be done
+ *     @body_size: maximum body size used for message in 32-bit words.
+ *
+ *     Return the maximum number of SG elements in a SG list.
+ */
+u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
+{
+       i2o_status_block *sb = c->status_block.virt;
+       u16 sg_count =
+           (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
+           body_size;
+
+       if (c->pae_support) {
+               /*
+                * for 64-bit a SG attribute element must be added and each
+                * SG element needs 12 bytes instead of 8.
+                */
+               sg_count -= 2;
+               sg_count /= 3;
+       } else
+               sg_count /= 2;
+
+       if (c->short_req && (sg_count > 8))
+               sg_count = 8;
+
+       return sg_count;
+}
+EXPORT_SYMBOL_GPL(i2o_sg_tablesize);
+
+
+/**
+ *     i2o_dma_map_single - Map pointer to controller and fill in I2O message.
+ *     @c: I2O controller
+ *     @ptr: pointer to the data which should be mapped
+ *     @size: size of data in bytes
+ *     @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ *     @sg_ptr: pointer to the SG list inside the I2O message
+ *
+ *     This function does all necessary DMA handling and also writes the I2O
+ *     SGL elements into the I2O message. For details on DMA handling see also
+ *     dma_map_single(). The pointer sg_ptr will only be set to the end of the
+ *     SG list if the allocation was successful.
+ *
+ *     Returns DMA address which must be checked for failures using
+ *     dma_mapping_error().
+ */
+dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
+                                           size_t size,
+                                           enum dma_data_direction direction,
+                                           u32 ** sg_ptr)
+{
+       u32 sg_flags;
+       u32 *mptr = *sg_ptr;
+       dma_addr_t dma_addr;
+
+       switch (direction) {
+       case DMA_TO_DEVICE:
+               sg_flags = 0xd4000000;
+               break;
+       case DMA_FROM_DEVICE:
+               sg_flags = 0xd0000000;
+               break;
+       default:
+               return 0;
+       }
+
+       dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
+       if (!dma_mapping_error(&c->pdev->dev, dma_addr)) {
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+               if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+                       *mptr++ = cpu_to_le32(0x7C020002);
+                       *mptr++ = cpu_to_le32(PAGE_SIZE);
+               }
+#endif
+
+               *mptr++ = cpu_to_le32(sg_flags | size);
+               *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+               if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+                       *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
+#endif
+               *sg_ptr = mptr;
+       }
+       return dma_addr;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_map_single);
+
+/**
+ *     i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
+ *     @c: I2O controller
+ *     @sg: SG list to be mapped
+ *     @sg_count: number of elements in the SG list
+ *     @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ *     @sg_ptr: pointer to the SG list inside the I2O message
+ *
+ *     This function does all necessary DMA handling and also writes the I2O
+ *     SGL elements into the I2O message. For details on DMA handling see also
+ *     dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
+ *     list if the allocation was successful.
+ *
+ *     Returns 0 on failure or 1 on success.
+ */
+int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg,
+           int sg_count, enum dma_data_direction direction, u32 ** sg_ptr)
+{
+       u32 sg_flags;
+       u32 *mptr = *sg_ptr;
+
+       switch (direction) {
+       case DMA_TO_DEVICE:
+               sg_flags = 0x14000000;
+               break;
+       case DMA_FROM_DEVICE:
+               sg_flags = 0x10000000;
+               break;
+       default:
+               return 0;
+       }
+
+       sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
+       if (!sg_count)
+               return 0;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+       if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+               *mptr++ = cpu_to_le32(0x7C020002);
+               *mptr++ = cpu_to_le32(PAGE_SIZE);
+       }
+#endif
+
+       while (sg_count-- > 0) {
+               if (!sg_count)
+                       sg_flags |= 0xC0000000;
+               *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
+               *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+               if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+                       *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
+#endif
+               sg = sg_next(sg);
+       }
+       *sg_ptr = mptr;
+
+       return 1;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_map_sg);
+
+/**
+ *     i2o_dma_alloc - Allocate DMA memory
+ *     @dev: struct device pointer to the PCI device of the I2O controller
+ *     @addr: i2o_dma struct which should get the DMA buffer
+ *     @len: length of the new DMA memory
+ *
+ *     Allocate a coherent DMA memory and write the pointers into addr.
+ *
+ *     Returns 0 on success or -ENOMEM on failure.
+ */
+int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       int dma_64 = 0;
+
+       mutex_lock(&mem_lock);
+       if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
+               dma_64 = 1;
+               if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+                       mutex_unlock(&mem_lock);
+                       return -ENOMEM;
+               }
+       }
+
+       addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL);
+
+       if ((sizeof(dma_addr_t) > 4) && dma_64)
+               if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+                       printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
+       mutex_unlock(&mem_lock);
+
+       if (!addr->virt)
+               return -ENOMEM;
+
+       memset(addr->virt, 0, len);
+       addr->len = len;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_alloc);
+
+
+/**
+ *     i2o_dma_free - Free DMA memory
+ *     @dev: struct device pointer to the PCI device of the I2O controller
+ *     @addr: i2o_dma struct which contains the DMA buffer
+ *
+ *     Free a coherent DMA memory and set virtual address of addr to NULL.
+ */
+void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
+{
+       if (addr->virt) {
+               if (addr->phys)
+                       dma_free_coherent(dev, addr->len, addr->virt,
+                                         addr->phys);
+               else
+                       kfree(addr->virt);
+               addr->virt = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(i2o_dma_free);
+
+
+/**
+ *     i2o_dma_realloc - Realloc DMA memory
+ *     @dev: struct device pointer to the PCI device of the I2O controller
+ *     @addr: pointer to a i2o_dma struct DMA buffer
+ *     @len: new length of memory
+ *
+ *     If there was something allocated in the addr, free it first. If len > 0
+ *     than try to allocate it and write the addresses back to the addr
+ *     structure. If len == 0 set the virtual address to NULL.
+ *
+ *     Returns the 0 on success or negative error code on failure.
+ */
+int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len)
+{
+       i2o_dma_free(dev, addr);
+
+       if (len)
+               return i2o_dma_alloc(dev, addr, len);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_realloc);
+
+/*
+ *     i2o_pool_alloc - Allocate an slab cache and mempool
+ *     @mempool: pointer to struct i2o_pool to write data into.
+ *     @name: name which is used to identify cache
+ *     @size: size of each object
+ *     @min_nr: minimum number of objects
+ *
+ *     First allocates a slab cache with name and size. Then allocates a
+ *     mempool which uses the slab cache for allocation and freeing.
+ *
+ *     Returns 0 on success or negative error code on failure.
+ */
+int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
+                                size_t size, int min_nr)
+{
+       pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+       if (!pool->name)
+               goto exit;
+       strcpy(pool->name, name);
+
+       pool->slab =
+           kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL);
+       if (!pool->slab)
+               goto free_name;
+
+       pool->mempool = mempool_create_slab_pool(min_nr, pool->slab);
+       if (!pool->mempool)
+               goto free_slab;
+
+       return 0;
+
+free_slab:
+       kmem_cache_destroy(pool->slab);
+
+free_name:
+       kfree(pool->name);
+
+exit:
+       return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(i2o_pool_alloc);
+
+/*
+ *     i2o_pool_free - Free slab cache and mempool again
+ *     @mempool: pointer to struct i2o_pool which should be freed
+ *
+ *     Note that you have to return all objects to the mempool again before
+ *     calling i2o_pool_free().
+ */
+void i2o_pool_free(struct i2o_pool *pool)
+{
+       mempool_destroy(pool->mempool);
+       kmem_cache_destroy(pool->slab);
+       kfree(pool->name);
+};
+EXPORT_SYMBOL_GPL(i2o_pool_free);
index 685a89547a51fdc26929c5df2202b1f353188d7a..610ef1204e68f83ccfb2cd35f98ab5d3472c2229 100644 (file)
@@ -186,31 +186,29 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
                }
        }
 
-       if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
+       if (i2o_dma_alloc(dev, &c->status, 8)) {
                i2o_pci_free(c);
                return -ENOMEM;
        }
 
-       if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt), GFP_KERNEL)) {
+       if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) {
                i2o_pci_free(c);
                return -ENOMEM;
        }
 
-       if (i2o_dma_alloc(dev, &c->dlct, 8192, GFP_KERNEL)) {
+       if (i2o_dma_alloc(dev, &c->dlct, 8192)) {
                i2o_pci_free(c);
                return -ENOMEM;
        }
 
-       if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block),
-                         GFP_KERNEL)) {
+       if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) {
                i2o_pci_free(c);
                return -ENOMEM;
        }
 
-       if (i2o_dma_alloc
-           (dev, &c->out_queue,
-            I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
-            sizeof(u32), GFP_KERNEL)) {
+       if (i2o_dma_alloc(dev, &c->out_queue,
+               I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
+                               sizeof(u32))) {
                i2o_pci_free(c);
                return -ENOMEM;
        }
index a726f3b01a6b36debf060b647c4384a4aab8f1b3..efd3aa08b88bb85c3ca8855084a8bd1314c2c30f 100644 (file)
@@ -15,7 +15,7 @@ if MISC_DEVICES
 
 config ATMEL_PWM
        tristate "Atmel AT32/AT91 PWM support"
-       depends on AVR32 || ARCH_AT91
+       depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
        help
          This option enables device driver support for the PWM channels
          on certain Atmel prcoessors.  Pulse Width Modulation is used for
@@ -409,6 +409,7 @@ config EEEPC_LAPTOP
        depends on BACKLIGHT_CLASS_DEVICE
        depends on HWMON
        depends on EXPERIMENTAL
+       depends on RFKILL
        ---help---
          This driver supports the Fn-Fx keys on Eee PC laptops.
          It also adds the ability to switch camera/wlan on/off.
index 6d407c2a4f91d80e54d5885e741ce436fb21aa31..5dabfb69ee537f25a1bc93814c0e894ebf3ba494 100644 (file)
@@ -309,7 +309,7 @@ static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
        return -EINVAL;
 }
 
-void hp_wmi_notify(u32 value, void *context)
+static void hp_wmi_notify(u32 value, void *context)
 {
        struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
        static struct key_entry *key;
index daf585689ce33a0e77a07bd3991e2165f8c04acb..abdebe347383903d93f43e59365a76ef2b6db48f 100644 (file)
@@ -399,9 +399,9 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
                goto err_irq;
        }
 
-       if (IS_ERR(device_create_drvdata(phantom_class, &pdev->dev,
-                                        MKDEV(phantom_major, minor),
-                                        NULL, "phantom%u", minor)))
+       if (IS_ERR(device_create(phantom_class, &pdev->dev,
+                                MKDEV(phantom_major, minor), NULL,
+                                "phantom%u", minor)))
                dev_err(&pdev->dev, "can't create device\n");
 
        pci_set_drvdata(pdev, pht);
index 40df7cb3f0a571fc6ed4645a13e1c9dae83c036b..f93f03a9e6e9e3c0cb1d034b7f746386df76bfe2 100644 (file)
@@ -30,9 +30,9 @@
 /*
  * Size used to map GRU GSeg
  */
-#if defined CONFIG_IA64
+#if defined(CONFIG_IA64)
 #define GRU_GSEG_PAGESIZE      (256 * 1024UL)
-#elif defined CONFIG_X86_64
+#elif defined(CONFIG_X86_64)
 #define GRU_GSEG_PAGESIZE      (256 * 1024UL)          /* ZZZ 2MB ??? */
 #else
 #error "Unsupported architecture"
index 0dc36225c7c6c2f76b909cec45342d4ede4b9a80..48762e7b98be65a5b3758489657a5d1675cf5de0 100644 (file)
@@ -26,7 +26,7 @@
  * Architecture dependent functions
  */
 
-#if defined CONFIG_IA64
+#if defined(CONFIG_IA64)
 #include <linux/compiler.h>
 #include <asm/intrinsics.h>
 #define __flush_cache(p)               ia64_fc(p)
@@ -36,7 +36,7 @@
                        barrier();                                      \
                        *((volatile int *)(p)) = v; /* force st.rel */  \
                } while (0)
-#elif defined CONFIG_X86_64
+#elif defined(CONFIG_X86_64)
 #define __flush_cache(p)               clflush(p)
 #define gru_ordered_store_int(p,v)                                     \
                do {                                                    \
@@ -299,6 +299,7 @@ static inline void gru_flush_cache(void *p)
 static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
 {
        gru_ordered_store_int(ins, op32);
+       gru_flush_cache(ins);
 }
 
 
@@ -604,8 +605,9 @@ static inline int gru_get_cb_substatus(void *cb)
 static inline int gru_check_status(void *cb)
 {
        struct gru_control_block_status *cbs = (void *)cb;
-       int ret = cbs->istatus;
+       int ret;
 
+       ret = cbs->istatus;
        if (ret == CBS_CALL_OS)
                ret = gru_check_status_proc(cb);
        return ret;
@@ -617,7 +619,7 @@ static inline int gru_check_status(void *cb)
 static inline int gru_wait(void *cb)
 {
        struct gru_control_block_status *cbs = (void *)cb;
-       int ret = cbs->istatus;;
+       int ret = cbs->istatus;
 
        if (ret != CBS_IDLE)
                ret = gru_wait_proc(cb);
index 3d33015bbf31a18d2a6aca7c0a662788abc34b97..8c389d606c304c8b9b34022c8d2e71ceba4bb6e8 100644 (file)
@@ -214,12 +214,14 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
 }
 
 /*
- *
  * atomic_pte_lookup
  *
  * Convert a user virtual address to a physical address
  * Only supports Intel large pages (2MB only) on x86_64.
  *     ZZZ - hugepage support is incomplete
+ *
+ * NOTE: mmap_sem is already held on entry to this function. This
+ * guarantees existence of the page tables.
  */
 static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
        int write, unsigned long *paddr, int *pageshift)
@@ -229,9 +231,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
        pud_t *pudp;
        pte_t pte;
 
-       WARN_ON(irqs_disabled());               /* ZZZ debug */
-
-       local_irq_disable();
        pgdp = pgd_offset(vma->vm_mm, vaddr);
        if (unlikely(pgd_none(*pgdp)))
                goto err;
@@ -250,8 +249,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
 #endif
                pte = *pte_offset_kernel(pmdp, vaddr);
 
-       local_irq_enable();
-
        if (unlikely(!pte_present(pte) ||
                     (write && (!pte_write(pte) || !pte_dirty(pte)))))
                return 1;
@@ -324,6 +321,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
         * Atomic lookup is faster & usually works even if called in non-atomic
         * context.
         */
+       rmb();  /* Must/check ms_range_active before loading PTEs */
        ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift);
        if (ret) {
                if (!cb)
@@ -543,6 +541,7 @@ int gru_get_exception_detail(unsigned long arg)
                ucbnum = get_cb_number((void *)excdet.cb);
                cbrnum = thread_cbr_number(gts, ucbnum);
                cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
+               prefetchw(cbe);         /* Harmless on hardware, required for emulator */
                excdet.opc = cbe->opccpy;
                excdet.exopc = cbe->exopccpy;
                excdet.ecause = cbe->ecause;
index d61cee796efdc234aba44fdcb5969283f24780d7..5c027b6b4e5a7438815b290e09a99a0290bf55f5 100644 (file)
@@ -113,7 +113,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
                return -EPERM;
 
        if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
-                       vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
+                               vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
                return -EINVAL;
 
        vma->vm_flags |=
@@ -398,6 +398,12 @@ static int __init gru_init(void)
        irq = get_base_irq();
        for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
                ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
+               /* TODO: fix irq handling on x86. For now ignore failures because
+                * interrupts are not required & not yet fully supported */
+               if (ret) {
+                       printk("!!!WARNING: GRU ignoring request failure!!!\n");
+                       ret = 0;
+               }
                if (ret) {
                        printk(KERN_ERR "%s: request_irq failed\n",
                               GRU_DRIVER_ID_STR);
index d16031d626730b2dd36e0fac1d27264f4c8c9857..b63018d60fe1a56b22e0cc2c02cc43b650dba7f6 100644 (file)
 #define GSEGPOFF(h)            ((h) & (GRU_SIZE - 1))
 
 /* Convert an arbitrary handle address to the beginning of the GRU segment */
-#ifndef __PLUGIN__
 #define GRUBASE(h)             ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
-#else
-extern void *gmu_grubase(void *h);
-#define GRUBASE(h)             gmu_grubase(h)
-#endif
 
 /* General addressing macros. */
 static inline void *get_gseg_base_address(void *base, int ctxnum)
index dfd49af0fe18220d41a4afc438fc0b74c3439a6f..880c55dfb66266dfd53cae3dea2492b986ff5744 100644 (file)
@@ -122,6 +122,7 @@ int gru_get_cb_exception_detail(void *cb,
        struct gru_control_block_extended *cbe;
 
        cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
+       prefetchw(cbe);         /* Harmless on hardware, required for emulator */
        excdet->opc = cbe->opccpy;
        excdet->exopc = cbe->exopccpy;
        excdet->ecause = cbe->ecause;
@@ -466,7 +467,7 @@ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
        STAT(mesq_send);
        BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES);
 
-       clines = (bytes + GRU_CACHE_LINE_BYTES - 1) / GRU_CACHE_LINE_BYTES;
+       clines = DIV_ROUND_UP(bytes, GRU_CACHE_LINE_BYTES);
        if (gru_get_cpu_resources(bytes, &cb, &dsr))
                return MQE_BUG_NO_RESOURCES;
        memcpy(dsr, mesg, bytes);
index 0eeb8dddd2f51396a85d726a8286f09b68348580..e11e1ac509002c862553744d606e4582b2bf3238 100644 (file)
@@ -432,29 +432,35 @@ static inline long gru_copy_handle(void *d, void *s)
        return GRU_HANDLE_BYTES;
 }
 
-/* rewrite in assembly & use lots of prefetch */
-static void gru_load_context_data(void *save, void *grubase, int ctxnum,
-                                 unsigned long cbrmap, unsigned long dsrmap)
+static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
+                               unsigned long length)
 {
-       void *gseg, *cb, *cbe;
-       unsigned long length;
        int i, scr;
 
-       gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
-       length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
        prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES,
                      GRU_CACHE_LINE_BYTES);
 
-       cb = gseg + GRU_CB_BASE;
-       cbe = grubase + GRU_CBE_BASE;
        for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
                prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES);
                prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1,
                              GRU_CACHE_LINE_BYTES);
                cb += GRU_HANDLE_STRIDE;
        }
+}
+
+static void gru_load_context_data(void *save, void *grubase, int ctxnum,
+                                 unsigned long cbrmap, unsigned long dsrmap)
+{
+       void *gseg, *cb, *cbe;
+       unsigned long length;
+       int i, scr;
 
+       gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
        cb = gseg + GRU_CB_BASE;
+       cbe = grubase + GRU_CBE_BASE;
+       length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
+       gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
+
        for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
                save += gru_copy_handle(cb, save);
                save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save);
@@ -472,15 +478,16 @@ static void gru_unload_context_data(void *save, void *grubase, int ctxnum,
        int i, scr;
 
        gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
-
        cb = gseg + GRU_CB_BASE;
        cbe = grubase + GRU_CBE_BASE;
+       length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
+       gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
+
        for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
                save += gru_copy_handle(save, cb);
                save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE);
                cb += GRU_HANDLE_STRIDE;
        }
-       length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
        memcpy(save, gseg + GRU_DS_BASE, length);
 }
 
index c16028872bbbc0b19c23c8cdb895ad91a22fa3a4..1b9fc3c6b8752240c591aa23ed6a7d0f13bbea44 100644 (file)
@@ -172,7 +172,7 @@ struct mmc_omap_host {
        struct omap_mmc_platform_data *pdata;
 };
 
-void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
+static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
 {
        unsigned long tick_ns;
 
@@ -182,7 +182,7 @@ void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
        }
 }
 
-void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
+static void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
 {
        unsigned long flags;
 
@@ -1455,7 +1455,9 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
 
        host->irq = irq;
        host->phys_base = host->mem_res->start;
-       host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);
+       host->virt_base = ioremap(res->start, res->end - res->start + 1);
+       if (!host->virt_base)
+               goto err_ioremap;
 
        if (cpu_is_omap24xx()) {
                host->iclk = clk_get(&pdev->dev, "mmc_ick");
@@ -1510,6 +1512,8 @@ err_free_iclk:
                clk_put(host->iclk);
        }
 err_free_mmc_host:
+       iounmap(host->virt_base);
+err_ioremap:
        kfree(host);
 err_free_mem_region:
        release_mem_region(res->start, res->end - res->start + 1);
@@ -1536,6 +1540,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
        if (host->fclk && !IS_ERR(host->fclk))
                clk_put(host->fclk);
 
+       iounmap(host->virt_base);
        release_mem_region(pdev->resource[0].start,
                           pdev->resource[0].end - pdev->resource[0].start + 1);
 
index e00d424e6575da02ed20246b44c6545c1cbe8b34..1c74762dec89c25f73c3d7ab7fa4fbdaf2e08688 100644 (file)
@@ -26,13 +26,11 @@ static void mtd_notify_add(struct mtd_info* mtd)
        if (!mtd)
                return;
 
-       device_create_drvdata(mtd_class, NULL,
-                             MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
-                             NULL, "mtd%d", mtd->index);
+       device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+                     NULL, "mtd%d", mtd->index);
 
-       device_create_drvdata(mtd_class, NULL,
-                             MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
-                             NULL, "mtd%dro", mtd->index);
+       device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+                     NULL, "mtd%dro", mtd->index);
 }
 
 static void mtd_notify_remove(struct mtd_info* mtd)
index edb90b58a9b16980bd42066f6026bbd1ca7c0667..9a06dc93ee0d36a14428b618d810fb2ece02140d 100644 (file)
@@ -564,10 +564,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
 
        for ( ; ret <= 0 && *types; types++) {
                parser = get_partition_parser(*types);
-#ifdef CONFIG_KMOD
                if (!parser && !request_module("%s", *types))
                                parser = get_partition_parser(*types);
-#endif
                if (!parser) {
                        printk(KERN_NOTICE "%s partition parsing not available\n",
                               *types);
index 26d42987971fc9480520454fd2944e23c5f47641..782994ead0e83e1a123d011ac867ee3c9ea08c17 100644 (file)
@@ -145,7 +145,7 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
 
 static int ams_delta_nand_ready(struct mtd_info *mtd)
 {
-       return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB);
+       return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
 }
 
 /*
@@ -185,7 +185,7 @@ static int __init ams_delta_init(void)
        this->read_buf = ams_delta_read_buf;
        this->verify_buf = ams_delta_verify_buf;
        this->cmd_ctrl = ams_delta_hwcontrol;
-       if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) {
+       if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) {
                this->dev_ready = ams_delta_nand_ready;
        } else {
                this->dev_ready = NULL;
index b9d097c9f6bbb88613e71ce53a42d9388a51fbf2..3a7bc524af33cebb0ca332f81440442099b86e27 100644 (file)
@@ -40,7 +40,7 @@
                v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
                v1.15 1/31/98 Faster recovery for Tx errors. -djb
                v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
-               v1.18 12Mar2001 Andrew Morton <andrewm@uow.edu.au>
+               v1.18 12Mar2001 Andrew Morton
                        - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
                        - Reviewed against 1.18 from scyld.com
                v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com>
index a28de8182802c68698f86f966acb20a2032d74c4..7107620f615dfd0d17bef1b06fce245ef12411f0 100644 (file)
@@ -36,8 +36,7 @@
 
   Alan Cox          : Removed 1.2 support, added 2.1 extra counters.
 
-  Andrew Morton     : andrewm@uow.edu.au
-                    : Kernel 2.3.48
+  Andrew Morton     : Kernel 2.3.48
                     : Handle kmalloc() failures
                     : Other resource allocation fixes
                     : Add SMP locks
@@ -49,7 +48,7 @@
                     : Fixed an out-of-mem bug in dma_rx()
                     : Updated Documentation/networking/cs89x0.txt
 
-  Andrew Morton     : andrewm@uow.edu.au / Kernel 2.3.99-pre1
+  Andrew Morton     : Kernel 2.3.99-pre1
                     : Use skb_reserve to longword align IP header (two places)
                     : Remove a delay loop from dma_rx()
                     : Replace '100' with HZ
                     : Added 'cs89x0_dma=N' kernel boot option
                     : Correctly initialise lp->lock in non-module compile
 
-  Andrew Morton     : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1
+  Andrew Morton     : Kernel 2.3.99-pre4-1
                     : MOD_INC/DEC race fix (see
                     : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
 
-  Andrew Morton     : andrewm@uow.edu.au / Kernel 2.4.0-test7-pre2
+  Andrew Morton     : Kernel 2.4.0-test7-pre2
                     : Enhanced EEPROM support to cover more devices,
                     :   abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch
                     :   (Jason Gunthorpe <jgg@ualberta.ca>)
 #include "cs89x0.h"
 
 static char version[] __initdata =
-"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
+"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
 
 #define DRV_NAME "cs89x0"
 
@@ -1877,7 +1876,7 @@ MODULE_PARM_DESC(dmasize , "(ignored)");
 MODULE_PARM_DESC(use_dma , "(ignored)");
 #endif
 
-MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>");
+MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
 MODULE_LICENSE("GPL");
 
 
index bcec7320895c889e96afaf7c067fa80438a4447a..78a1628c9892f71514cd781eed6a62b56fa0de48 100644 (file)
@@ -62,3 +62,15 @@ config IBM_NEW_EMAC_TAH
 config IBM_NEW_EMAC_EMAC4
        bool
        default n
+
+config IBM_NEW_EMAC_NO_FLOW_CTRL
+       bool
+       default n
+
+config IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
+       bool
+       default n
+
+config IBM_NEW_EMAC_MAL_COMMON_ERR
+       bool
+       default n
index 58dfd32ccca8c1a82c2d7569bfad8a4812d11d28..efcf21c9f5c7a825ee66ca0671e689c90c13f5ff 100644 (file)
@@ -202,13 +202,15 @@ static inline int emac_phy_supports_gige(int phy_mode)
 {
        return  phy_mode == PHY_MODE_GMII ||
                phy_mode == PHY_MODE_RGMII ||
+               phy_mode == PHY_MODE_SGMII ||
                phy_mode == PHY_MODE_TBI ||
                phy_mode == PHY_MODE_RTBI;
 }
 
 static inline int emac_phy_gpcs(int phy_mode)
 {
-       return  phy_mode == PHY_MODE_TBI ||
+       return  phy_mode == PHY_MODE_SGMII ||
+               phy_mode == PHY_MODE_TBI ||
                phy_mode == PHY_MODE_RTBI;
 }
 
@@ -562,8 +564,9 @@ static int emac_configure(struct emac_instance *dev)
        switch (dev->phy.speed) {
        case SPEED_1000:
                if (emac_phy_gpcs(dev->phy.mode)) {
-                       mr1 |= EMAC_MR1_MF_1000GPCS |
-                               EMAC_MR1_MF_IPPA(dev->phy.address);
+                       mr1 |= EMAC_MR1_MF_1000GPCS | EMAC_MR1_MF_IPPA(
+                               (dev->phy.gpcs_address != 0xffffffff) ?
+                                dev->phy.gpcs_address : dev->phy.address);
 
                        /* Put some arbitrary OUI, Manuf & Rev IDs so we can
                         * identify this GPCS PHY later.
@@ -675,8 +678,12 @@ static int emac_configure(struct emac_instance *dev)
        out_be32(&p->iser,  r);
 
        /* We need to take GPCS PHY out of isolate mode after EMAC reset */
-       if (emac_phy_gpcs(dev->phy.mode))
-               emac_mii_reset_phy(&dev->phy);
+       if (emac_phy_gpcs(dev->phy.mode)) {
+               if (dev->phy.gpcs_address != 0xffffffff)
+                       emac_mii_reset_gpcs(&dev->phy);
+               else
+                       emac_mii_reset_phy(&dev->phy);
+       }
 
        return 0;
 }
@@ -881,7 +888,9 @@ static int emac_mdio_read(struct net_device *ndev, int id, int reg)
        struct emac_instance *dev = netdev_priv(ndev);
        int res;
 
-       res = __emac_mdio_read(dev->mdio_instance ? dev->mdio_instance : dev,
+       res = __emac_mdio_read((dev->mdio_instance &&
+                               dev->phy.gpcs_address != id) ?
+                               dev->mdio_instance : dev,
                               (u8) id, (u8) reg);
        return res;
 }
@@ -890,7 +899,9 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
 {
        struct emac_instance *dev = netdev_priv(ndev);
 
-       __emac_mdio_write(dev->mdio_instance ? dev->mdio_instance : dev,
+       __emac_mdio_write((dev->mdio_instance &&
+                          dev->phy.gpcs_address != id) ?
+                          dev->mdio_instance : dev,
                          (u8) id, (u8) reg, (u16) val);
 }
 
@@ -2382,7 +2393,11 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
                 * XXX I probably should move these settings to the dev tree
                 */
                dev->phy.address = -1;
-               dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII;
+               dev->phy.features = SUPPORTED_MII;
+               if (emac_phy_supports_gige(dev->phy_mode))
+                       dev->phy.features |= SUPPORTED_1000baseT_Full;
+               else
+                       dev->phy.features |= SUPPORTED_100baseT_Full;
                dev->phy.pause = 1;
 
                return 0;
@@ -2421,7 +2436,9 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
                 * Note that the busy_phy_map is currently global
                 * while it should probably be per-ASIC...
                 */
-               dev->phy.address = dev->cell_index;
+               dev->phy.gpcs_address = dev->gpcs_address;
+               if (dev->phy.gpcs_address == 0xffffffff)
+                       dev->phy.address = dev->cell_index;
        }
 
        emac_configure(dev);
@@ -2531,6 +2548,8 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                dev->phy_address = 0xffffffff;
        if (emac_read_uint_prop(np, "phy-map", &dev->phy_map, 0))
                dev->phy_map = 0xffffffff;
+       if (emac_read_uint_prop(np, "gpcs-address", &dev->gpcs_address, 0))
+               dev->gpcs_address = 0xffffffff;
        if (emac_read_uint_prop(np->parent, "clock-frequency", &dev->opb_bus_freq, 1))
                return -ENXIO;
        if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0))
@@ -2585,6 +2604,8 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                if (of_device_is_compatible(np, "ibm,emac-440ep") ||
                    of_device_is_compatible(np, "ibm,emac-440gr"))
                        dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
+               if (of_device_is_compatible(np, "ibm,emac-405ez"))
+                       dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x;
        }
 
        /* Fixup some feature bits based on the device tree */
@@ -2842,6 +2863,9 @@ static int __devinit emac_probe(struct of_device *ofdev,
               ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
               ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
 
+       if (dev->phy_mode == PHY_MODE_SGMII)
+               printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name);
+
        if (dev->phy.address >= 0)
                printk("%s: found %s PHY (0x%02x)\n", ndev->name,
                       dev->phy.def->name, dev->phy.address);
index 5ca70e55b6c51a49509953985e24f92928f02e7e..18d56c6c4238e75673e34c3bdd7c0ec2a55563bb 100644 (file)
@@ -190,6 +190,9 @@ struct emac_instance {
        struct delayed_work             link_work;
        int                             link_polling;
 
+       /* GPCS PHY infos */
+       u32                             gpcs_address;
+
        /* Shared MDIO if any */
        u32                             mdio_ph;
        struct of_device                *mdio_dev;
@@ -344,6 +347,9 @@ enum {
 #endif
 #ifdef CONFIG_IBM_NEW_EMAC_RGMII
            EMAC_FTR_HAS_RGMII  |
+#endif
+#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL
+           EMAC_FTR_NO_FLOW_CONTROL_40x |
 #endif
        EMAC_FTR_460EX_PHY_CLK_FIX |
        EMAC_FTR_440EP_PHY_CLK_FIX,
index 10c267b2b9610b1e446a4fe32e4deba9c5700976..1839d3f154a3f3256f15b9d842f86fbd407a8fe5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 
 #include "core.h"
+#include <asm/dcr-regs.h>
 
 static int mal_count;
 
@@ -279,6 +280,10 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance)
        mal_schedule_poll(mal);
        set_mal_dcrn(mal, MAL_TXEOBISR, r);
 
+       if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
+               mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
+                               (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX));
+
        return IRQ_HANDLED;
 }
 
@@ -293,6 +298,10 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance)
        mal_schedule_poll(mal);
        set_mal_dcrn(mal, MAL_RXEOBISR, r);
 
+       if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
+               mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
+                               (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX));
+
        return IRQ_HANDLED;
 }
 
@@ -336,6 +345,25 @@ static irqreturn_t mal_rxde(int irq, void *dev_instance)
        return IRQ_HANDLED;
 }
 
+static irqreturn_t mal_int(int irq, void *dev_instance)
+{
+       struct mal_instance *mal = dev_instance;
+       u32 esr = get_mal_dcrn(mal, MAL_ESR);
+
+       if (esr & MAL_ESR_EVB) {
+               /* descriptor error */
+               if (esr & MAL_ESR_DE) {
+                       if (esr & MAL_ESR_CIDT)
+                               return mal_rxde(irq, dev_instance);
+                       else
+                               return mal_txde(irq, dev_instance);
+               } else { /* SERR */
+                       return mal_serr(irq, dev_instance);
+               }
+       }
+       return IRQ_HANDLED;
+}
+
 void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac)
 {
        /* Spinlock-type semantics: only one caller disable poll at a time */
@@ -493,6 +521,8 @@ static int __devinit mal_probe(struct of_device *ofdev,
        unsigned int dcr_base;
        const u32 *prop;
        u32 cfg;
+       unsigned long irqflags;
+       irq_handler_t hdlr_serr, hdlr_txde, hdlr_rxde;
 
        mal = kzalloc(sizeof(struct mal_instance), GFP_KERNEL);
        if (!mal) {
@@ -542,11 +572,21 @@ static int __devinit mal_probe(struct of_device *ofdev,
                goto fail;
        }
 
+       if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez"))
+               mal->features |= (MAL_FTR_CLEAR_ICINTSTAT |
+                               MAL_FTR_COMMON_ERR_INT);
+
        mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0);
        mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1);
        mal->serr_irq = irq_of_parse_and_map(ofdev->node, 2);
-       mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3);
-       mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4);
+
+       if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) {
+               mal->txde_irq = mal->rxde_irq = mal->serr_irq;
+       } else {
+               mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3);
+               mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4);
+       }
+
        if (mal->txeob_irq == NO_IRQ || mal->rxeob_irq == NO_IRQ ||
            mal->serr_irq == NO_IRQ || mal->txde_irq == NO_IRQ ||
            mal->rxde_irq == NO_IRQ) {
@@ -608,16 +648,26 @@ static int __devinit mal_probe(struct of_device *ofdev,
                             sizeof(struct mal_descriptor) *
                             mal_rx_bd_offset(mal, i));
 
-       err = request_irq(mal->serr_irq, mal_serr, 0, "MAL SERR", mal);
+       if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) {
+               irqflags = IRQF_SHARED;
+               hdlr_serr = hdlr_txde = hdlr_rxde = mal_int;
+       } else {
+               irqflags = 0;
+               hdlr_serr = mal_serr;
+               hdlr_txde = mal_txde;
+               hdlr_rxde = mal_rxde;
+       }
+
+       err = request_irq(mal->serr_irq, hdlr_serr, irqflags, "MAL SERR", mal);
        if (err)
                goto fail2;
-       err = request_irq(mal->txde_irq, mal_txde, 0, "MAL TX DE", mal);
+       err = request_irq(mal->txde_irq, hdlr_txde, irqflags, "MAL TX DE", mal);
        if (err)
                goto fail3;
        err = request_irq(mal->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
        if (err)
                goto fail4;
-       err = request_irq(mal->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
+       err = request_irq(mal->rxde_irq, hdlr_rxde, irqflags, "MAL RX DE", mal);
        if (err)
                goto fail5;
        err = request_irq(mal->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
index 717dc38b685885d0b0bd6fc8dac0610bc3042808..2f0a87360844afc3d1dd7eaaf3f3b0ebd6f6510c 100644 (file)
@@ -213,6 +213,8 @@ struct mal_instance {
        struct of_device        *ofdev;
        int                     index;
        spinlock_t              lock;
+
+       unsigned int features;
 };
 
 static inline u32 get_mal_dcrn(struct mal_instance *mal, int reg)
@@ -225,6 +227,38 @@ static inline void set_mal_dcrn(struct mal_instance *mal, int reg, u32 val)
        dcr_write(mal->dcr_host, reg, val);
 }
 
+/* Features of various MAL implementations */
+
+/* Set if you have interrupt coalescing and you have to clear the SDR
+ * register for TXEOB and RXEOB interrupts to work
+ */
+#define MAL_FTR_CLEAR_ICINTSTAT        0x00000001
+
+/* Set if your MAL has SERR, TXDE, and RXDE OR'd into a single UIC
+ * interrupt
+ */
+#define MAL_FTR_COMMON_ERR_INT 0x00000002
+
+enum {
+       MAL_FTRS_ALWAYS = 0,
+
+       MAL_FTRS_POSSIBLE =
+#ifdef CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
+               MAL_FTR_CLEAR_ICINTSTAT |
+#endif
+#ifdef CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR
+               MAL_FTR_COMMON_ERR_INT |
+#endif
+               0,
+};
+
+static inline int mal_has_feature(struct mal_instance *dev,
+               unsigned long feature)
+{
+       return (MAL_FTRS_ALWAYS & feature) ||
+               (MAL_FTRS_POSSIBLE & dev->features & feature);
+}
+
 /* Register MAL devices */
 int mal_init(void);
 void mal_exit(void);
index 9164abb72d9bc908bac64e89a7ed5ddf6db1174e..c40cd8df2212089e2f810bd1f25e0f6354dc42f3 100644 (file)
@@ -38,6 +38,16 @@ static inline void phy_write(struct mii_phy *phy, int reg, int val)
        phy->mdio_write(phy->dev, phy->address, reg, val);
 }
 
+static inline int gpcs_phy_read(struct mii_phy *phy, int reg)
+{
+       return phy->mdio_read(phy->dev, phy->gpcs_address, reg);
+}
+
+static inline void gpcs_phy_write(struct mii_phy *phy, int reg, int val)
+{
+       phy->mdio_write(phy->dev, phy->gpcs_address, reg, val);
+}
+
 int emac_mii_reset_phy(struct mii_phy *phy)
 {
        int val;
@@ -62,6 +72,37 @@ int emac_mii_reset_phy(struct mii_phy *phy)
        return limit <= 0;
 }
 
+int emac_mii_reset_gpcs(struct mii_phy *phy)
+{
+       int val;
+       int limit = 10000;
+
+       val = gpcs_phy_read(phy, MII_BMCR);
+       val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
+       val |= BMCR_RESET;
+       gpcs_phy_write(phy, MII_BMCR, val);
+
+       udelay(300);
+
+       while (limit--) {
+               val = gpcs_phy_read(phy, MII_BMCR);
+               if (val >= 0 && (val & BMCR_RESET) == 0)
+                       break;
+               udelay(10);
+       }
+       if ((val & BMCR_ISOLATE) && limit > 0)
+               gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
+
+       if (limit > 0 && phy->mode == PHY_MODE_SGMII) {
+               /* Configure GPCS interface to recommended setting for SGMII */
+               gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */
+               gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */
+               gpcs_phy_write(phy, 0x00, 0x0140); /* 1Gbps, FDX     */
+       }
+
+       return limit <= 0;
+}
+
 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
 {
        int ctl, adv;
@@ -332,6 +373,33 @@ static int m88e1111_init(struct mii_phy *phy)
        return  0;
 }
 
+static int m88e1112_init(struct mii_phy *phy)
+{
+       /*
+        * Marvell 88E1112 PHY needs to have the SGMII MAC
+        * interace (page 2) properly configured to
+        * communicate with the 460EX/GT GPCS interface.
+        */
+
+       u16 reg_short;
+
+       pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__);
+
+       /* Set access to Page 2 */
+       phy_write(phy, 0x16, 0x0002);
+
+       phy_write(phy, 0x00, 0x0040); /* 1Gbps */
+       reg_short = (u16)(phy_read(phy, 0x1a));
+       reg_short |= 0x8000; /* bypass Auto-Negotiation */
+       phy_write(phy, 0x1a, reg_short);
+       emac_mii_reset_phy(phy); /* reset MAC interface */
+
+       /* Reset access to Page 0 */
+       phy_write(phy, 0x16, 0x0000);
+
+       return  0;
+}
+
 static int et1011c_init(struct mii_phy *phy)
 {
        u16 reg_short;
@@ -384,11 +452,27 @@ static struct mii_phy_def m88e1111_phy_def = {
        .ops            = &m88e1111_phy_ops,
 };
 
+static struct mii_phy_ops m88e1112_phy_ops = {
+       .init           = m88e1112_init,
+       .setup_aneg     = genmii_setup_aneg,
+       .setup_forced   = genmii_setup_forced,
+       .poll_link      = genmii_poll_link,
+       .read_link      = genmii_read_link
+};
+
+static struct mii_phy_def m88e1112_phy_def = {
+       .phy_id         = 0x01410C90,
+       .phy_id_mask    = 0x0ffffff0,
+       .name           = "Marvell 88E1112 Ethernet",
+       .ops            = &m88e1112_phy_ops,
+};
+
 static struct mii_phy_def *mii_phy_table[] = {
        &et1011c_phy_def,
        &cis8201_phy_def,
        &bcm5248_phy_def,
        &m88e1111_phy_def,
+       &m88e1112_phy_def,
        &genmii_phy_def,
        NULL
 };
index 1b65c81f65577513af7ab34a52b7205fee10bab5..5d2bf4cbe50b9fb2ee365d1f30f7b0dee7d064fb 100644 (file)
@@ -57,6 +57,7 @@ struct mii_phy {
                                   or determined automaticaly */
        int address;            /* PHY address */
        int mode;               /* PHY mode */
+       int gpcs_address;       /* GPCS PHY address */
 
        /* 1: autoneg enabled, 0: disabled */
        int autoneg;
@@ -81,5 +82,6 @@ struct mii_phy {
  */
 int emac_mii_phy_probe(struct mii_phy *phy, int address);
 int emac_mii_reset_phy(struct mii_phy *phy);
+int emac_mii_reset_gpcs(struct mii_phy *phy);
 
 #endif /* __IBM_NEWEMAC_PHY_H */
index 36030241f7a9cf72102f09a019cae9ca54f0e169..2a9930e6e2afef50c5e3e711d5232bc8f9aead96 100644 (file)
@@ -67,9 +67,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type)
        const struct dongle_driver *drv = NULL;
        int err = -EINVAL;
 
-#ifdef CONFIG_KMOD
        request_module("irda-dongle-%d", type);
-#endif
 
        if (dev->dongle_drv != NULL)
                return -EBUSY;
index f11e900b437b66044b422da02e26fe4a4efdeff6..e11b03b2b25a776c2494951953feeb44777d2f84 100644 (file)
@@ -309,11 +309,6 @@ void phy_disconnect(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_disconnect);
 
-static int phy_compare_id(struct device *dev, void *data)
-{
-       return strcmp((char *)data, dev->bus_id) ? 0 : 1;
-}
-
 /**
  * phy_attach - attach a network device to a particular PHY device
  * @dev: network device to attach
@@ -337,8 +332,7 @@ struct phy_device *phy_attach(struct net_device *dev,
 
        /* Search the list of PHY devices on the mdio bus for the
         * PHY with the requested name */
-       d = bus_find_device(bus, NULL, (void *)bus_id, phy_compare_id);
-
+       d = bus_find_device_by_name(bus, NULL, bus_id);
        if (d) {
                phydev = to_phy_device(d);
        } else {
index 0ca0fcbb7c01f5dcb1f840dd31ca24d1696a83e6..7e857e938adb582ae432b26d35114e8099d51eb2 100644 (file)
@@ -866,8 +866,8 @@ static int __init ppp_init(void)
                        err = PTR_ERR(ppp_class);
                        goto out_chrdev;
                }
-               device_create_drvdata(ppp_class, NULL, MKDEV(PPP_MAJOR, 0),
-                                     NULL, "ppp");
+               device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
+                             "ppp");
        }
 
 out:
@@ -2127,13 +2127,9 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
            || ccp_option[1] < 2 || ccp_option[1] > data.length)
                goto out;
 
-       cp = find_compressor(ccp_option[0]);
-#ifdef CONFIG_KMOD
-       if (!cp) {
-               request_module("ppp-compress-%d", ccp_option[0]);
-               cp = find_compressor(ccp_option[0]);
-       }
-#endif /* CONFIG_KMOD */
+       cp = try_then_request_module(
+               find_compressor(ccp_option[0]),
+               "ppp-compress-%d", ccp_option[0]);
        if (!cp)
                goto out;
 
index c6898c1fc54d95de595fa990fc7b0977149c796a..03aecc97fb453d32eefb596dddba3f6286d909df 100644 (file)
@@ -115,13 +115,8 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol)
                goto out;
 
        rc = -EPROTONOSUPPORT;
-#ifdef CONFIG_KMOD
-       if (!pppox_protos[protocol]) {
-               char buffer[32];
-               sprintf(buffer, "pppox-proto-%d", protocol);
-               request_module(buffer);
-       }
-#endif
+       if (!pppox_protos[protocol])
+               request_module("pppox-proto-%d", protocol);
        if (!pppox_protos[protocol] ||
            !try_module_get(pppox_protos[protocol]->owner))
                goto out;
index f14051556c87d08098108f2f695a5bc2c6d35f5a..7f97f8d08c39eeba79eaa4da5cdfc5368d59487d 100644 (file)
@@ -388,8 +388,8 @@ static int __init cosa_init(void)
                goto out_chrdev;
        }
        for (i = 0; i < nr_cards; i++)
-               device_create_drvdata(cosa_class, NULL, MKDEV(cosa_major, i),
-                                     NULL, "cosa%d", i);
+               device_create(cosa_class, NULL, MKDEV(cosa_major, i), NULL,
+                             "cosa%d", i);
        err = 0;
        goto out;
 
index 74726990d59e0ae1851fe0d587032f355dabecbf..f05f584ab7bc960f9e8ba5ea29207ec63582bd2c 100644 (file)
@@ -1640,6 +1640,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
        return ret;
 }
 
+static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
+{
+       return -EOPNOTSUPP;
+}
+
 static struct ieee80211_ops ath9k_ops = {
        .tx                 = ath9k_tx,
        .start              = ath9k_start,
@@ -1664,7 +1669,8 @@ static struct ieee80211_ops ath9k_ops = {
        .get_tsf            = ath9k_get_tsf,
        .reset_tsf          = ath9k_reset_tsf,
        .tx_last_beacon     = NULL,
-       .ampdu_action       = ath9k_ampdu_action
+       .ampdu_action       = ath9k_ampdu_action,
+       .set_frag_threshold = ath9k_no_fragmentation,
 };
 
 static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
index f6003e7996afcd01aec848c726fa21d2080761c4..5155b8a760a7299cd5b01ae139821ec3c5dd0fe1 100644 (file)
@@ -833,12 +833,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
        switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
        case CSR_HW_REV_TYPE_5100:
        case CSR_HW_REV_TYPE_5300:
-               /* 5X00 wants in Celsius */
+       case CSR_HW_REV_TYPE_5350:
+               /* 5X00 and 5350 wants in Celsius */
                priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
                break;
        case CSR_HW_REV_TYPE_5150:
-       case CSR_HW_REV_TYPE_5350:
-               /* 5X50 wants in Kelvin */
+               /* 5150 wants in Kelvin */
                priv->hw_params.ct_kill_threshold =
                                CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
                break;
index 93944de923cafd0913979e1f45bf8a36023d2285..e2a58e477036e611da5ffc78abeda5748f7392ce 100644 (file)
@@ -2422,7 +2422,7 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
                        void *priv_sta)
 {
        struct iwl_lq_sta *lq_sta = priv_sta;
-       struct iwl_priv *priv = priv_r;
+       struct iwl_priv *priv __maybe_unused = priv_r;
 
        IWL_DEBUG_RATE("enter\n");
        kfree(lq_sta);
index a912fb68c09990fd12bfc18360e3d9c674b79e7f..297696de2da0554543f86cf1a50be458cba82b2b 100644 (file)
@@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
 int lbs_set_channel(struct lbs_private *priv, u8 channel)
 {
        struct cmd_ds_802_11_rf_channel cmd;
+#ifdef DEBUG
        u8 old_channel = priv->curbssparams.channel;
+#endif
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_CMD);
index c9e4a435b2fc04d916ae61e6db150345027a568c..1a019e98dac3ee8ef0b7be504a6cee8af6a36369 100644 (file)
@@ -533,11 +533,11 @@ static int __init init_mac80211_hwsim(void)
                data = hw->priv;
                data->hw = hw;
 
-               data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw,
-                                               "hwsim%d", i);
+               data->dev = device_create(hwsim_class, NULL, 0, hw,
+                                         "hwsim%d", i);
                if (IS_ERR(data->dev)) {
                        printk(KERN_DEBUG
-                              "mac80211_hwsim: device_create_drvdata "
+                              "mac80211_hwsim: device_create "
                               "failed (%ld)\n", PTR_ERR(data->dev));
                        err = -ENOMEM;
                        goto failed_drvdata;
index e585684e59a00012025c1e10990c979a8f0bf0eb..6fcf2bda7cdfbe5e0e356ab5adfee8982a2f6b27 100644 (file)
@@ -378,6 +378,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
        struct orinoco_private *priv = netdev_priv(dev);
        struct orinoco_pccard *card = priv->card;
        int err = 0;
+       unsigned long flags;
 
        if (! test_bit(0, &card->hard_reset_in_progress)) {
                err = orinoco_reinit_firmware(dev);
@@ -387,7 +388,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
                        return -EIO;
                }
 
-               spin_lock(&priv->lock);
+               spin_lock_irqsave(&priv->lock, flags);
 
                netif_device_attach(dev);
                priv->hw_unavailable--;
@@ -399,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
                                       dev->name, err);
                }
 
-               spin_unlock(&priv->lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
        }
 
        return err;
index 1994aa199d3726375c9b19346cea7e1babaab0d0..117c7d3a52b0ca4beb7e78f41da62d7a08797cae 100644 (file)
@@ -479,7 +479,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
        printk(KERN_ERR "p54: eeprom parse failed!\n");
        return err;
 }
-EXPORT_SYMBOL_GPL(p54_parse_eeprom);
 
 static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
 {
index 1912f5e9a0a98aff4d67e84180307060356ab349..75d749bccb0d13e17104b67e348c3723bbb1032b 100644 (file)
@@ -39,6 +39,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
        {USB_DEVICE(0x0846, 0x4200)},   /* Netgear WG121 */
        {USB_DEVICE(0x0846, 0x4210)},   /* Netgear WG121 the second ? */
        {USB_DEVICE(0x0846, 0x4220)},   /* Netgear WG111 */
+       {USB_DEVICE(0x09aa, 0x1000)},   /* Spinnaker Proto board */
        {USB_DEVICE(0x0cde, 0x0006)},   /* Medion 40900, Roper Europe */
        {USB_DEVICE(0x124a, 0x4023)},   /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
        {USB_DEVICE(0x1915, 0x2234)},   /* Linksys WUSB54G OEM */
@@ -63,8 +64,8 @@ static struct usb_device_id p54u_table[] __devinitdata = {
        {USB_DEVICE(0x0cde, 0x0006)},   /* Medion MD40900 */
        {USB_DEVICE(0x0cde, 0x0008)},   /* Sagem XG703A */
        {USB_DEVICE(0x0d8e, 0x3762)},   /* DLink DWL-G120 Cohiba */
-       {USB_DEVICE(0x09aa, 0x1000)},   /* Spinnaker Proto board */
        {USB_DEVICE(0x124a, 0x4025)},   /* IOGear GWU513 (GW3887IK chip) */
+       {USB_DEVICE(0x1260, 0xee22)},   /* SMC 2862W-G version 2 */
        {USB_DEVICE(0x13b1, 0x000a)},   /* Linksys WUSB54G ver 2 */
        {USB_DEVICE(0x13B1, 0x000C)},   /* Linksys WUSB54AG */
        {USB_DEVICE(0x1435, 0x0427)},   /* Inventel UR054G */
index 1676ac484790bfcc692b72a06f3e3feb3e0f2669..451d410ecdae4fae126ab835bdadd5647a4f13b8 100644 (file)
@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct txentry_desc txdesc;
        struct skb_frame_desc *skbdesc;
-       unsigned int iv_len;
+       unsigned int iv_len = 0;
 
        if (unlikely(rt2x00queue_full(queue)))
                return -EINVAL;
@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        entry->skb = skb;
        rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
+       if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
+               iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+
        /*
         * All information is retreived from the skb->cb array,
         * now we should claim ownership of the driver part of that
@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
         * the frame so we can provide it to the driver seperately.
         */
        if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
-           !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
-               (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
-               iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+           !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
                rt2x00crypto_tx_remove_iv(skb, iv_len);
        }
 
index e9902613e2eeb70695ca52a408e5d558eb515e52..431e3c78bf27668b00d87fc06120a7f909ae5090 100644 (file)
@@ -33,10 +33,13 @@ MODULE_LICENSE("GPL");
 static struct usb_device_id rtl8187_table[] __devinitdata = {
        /* Asus */
        {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
+       /* Belkin */
+       {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
        /* Realtek */
        {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
        {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
        {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
+       {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
        /* Netgear */
        {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
        {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
index b0c71c3be46769f3f08318c2bb81e51dee195f87..852789ad34b3e33e0094bbc2bce4496096e00209 100644 (file)
@@ -426,10 +426,11 @@ spectrum_cs_suspend(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
        struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
        int err = 0;
 
        /* Mark the device as stopped, to block IO until later */
-       spin_lock(&priv->lock);
+       spin_lock_irqsave(&priv->lock, flags);
 
        err = __orinoco_down(dev);
        if (err)
@@ -439,7 +440,7 @@ spectrum_cs_suspend(struct pcmcia_device *link)
        netif_device_detach(dev);
        priv->hw_unavailable++;
 
-       spin_unlock(&priv->lock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        return err;
 }
index 3c3dd403f5ddd9f58bed9f632baad6b72409e0ee..5c7a87e38951ede5ba1508b0aa0f583c8412e52d 100644 (file)
@@ -471,7 +471,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned int offset = offset_in_page(data);
        unsigned int len = skb_headlen(skb);
 
-       frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
+       frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
        if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
                printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
                       frags);
index 2f047e573d86cda7210d2346582324b5f126518e..f5f75844954cf829641774ec940307fd8e71b635 100644 (file)
@@ -126,7 +126,7 @@ static void nubus_advance(unsigned char **ptr, int len, int map)
        {
                while(not_useful(p,map))
                        p++;
-                       p++;
+               p++;
                len--;
        }
        *ptr = p;
index ad8ac1a8af28689acc7198b22fe95a888d62e6a6..7c79e94a35eac932a165367a11439a8af1d35cc0 100644 (file)
@@ -410,7 +410,7 @@ struct of_modalias_table {
        char *modalias;
 };
 static struct of_modalias_table of_modalias_table[] = {
-       /* Empty for now; add entries as needed */
+       { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
 };
 
 /**
@@ -420,13 +420,12 @@ static struct of_modalias_table of_modalias_table[] = {
  * @len:       Length of modalias value
  *
  * Based on the value of the compatible property, this routine will determine
- * an appropriate modalias value for a particular device tree node.  Three
- * separate methods are used to derive a modalias value.
+ * an appropriate modalias value for a particular device tree node.  Two
+ * separate methods are attempted to derive a modalias value.
  *
  * First method is to lookup the compatible value in of_modalias_table.
- * Second is to look for a "linux,<modalias>" entry in the compatible list
- * and used that for modalias.  Third is to strip off the manufacturer
- * prefix from the first compatible entry and use the remainder as modalias
+ * Second is to strip off the manufacturer prefix from the first
+ * compatible entry and use the remainder as modalias
  *
  * This routine returns 0 on success
  */
@@ -449,21 +448,7 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
        if (!compatible)
                return -ENODEV;
 
-       /* 2. search for linux,<modalias> entry */
-       p = compatible;
-       while (cplen > 0) {
-               if (!strncmp(p, "linux,", 6)) {
-                       p += 6;
-                       strlcpy(modalias, p, len);
-                       return 0;
-               }
-
-               i = strlen(p) + 1;
-               p += i;
-               cplen -= i;
-       }
-
-       /* 3. take first compatible entry and strip manufacturer */
+       /* 2. take first compatible entry and strip manufacturer */
        p = strchr(compatible, ',');
        if (!p)
                return -ENODEV;
@@ -473,3 +458,112 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
 }
 EXPORT_SYMBOL_GPL(of_modalias_node);
 
+/**
+ * of_parse_phandles_with_args - Find a node pointed by phandle in a list
+ * @np:                pointer to a device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name:        property name that specifies phandles' arguments count
+ * @index:     index of a phandle to parse out
+ * @out_node:  pointer to device_node struct pointer (will be filled)
+ * @out_args:  pointer to arguments pointer (will be filled)
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_node and out_args, on error returns
+ * appropriate errno value.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *     #list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *     #list-cells = <1>;
+ * }
+ *
+ * node3 {
+ *     list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args);
+ */
+int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
+                               const char *cells_name, int index,
+                               struct device_node **out_node,
+                               const void **out_args)
+{
+       int ret = -EINVAL;
+       const u32 *list;
+       const u32 *list_end;
+       int size;
+       int cur_index = 0;
+       struct device_node *node = NULL;
+       const void *args;
+
+       list = of_get_property(np, list_name, &size);
+       if (!list) {
+               ret = -ENOENT;
+               goto err0;
+       }
+       list_end = list + size / sizeof(*list);
+
+       while (list < list_end) {
+               const u32 *cells;
+               const phandle *phandle;
+
+               phandle = list;
+               args = list + 1;
+
+               /* one cell hole in the list = <>; */
+               if (!*phandle) {
+                       list++;
+                       goto next;
+               }
+
+               node = of_find_node_by_phandle(*phandle);
+               if (!node) {
+                       pr_debug("%s: could not find phandle\n",
+                                np->full_name);
+                       goto err0;
+               }
+
+               cells = of_get_property(node, cells_name, &size);
+               if (!cells || size != sizeof(*cells)) {
+                       pr_debug("%s: could not get %s for %s\n",
+                                np->full_name, cells_name, node->full_name);
+                       goto err1;
+               }
+
+               /* Next phandle is at offset of one phandle cell + #cells */
+               list += 1 + *cells;
+               if (list > list_end) {
+                       pr_debug("%s: insufficient arguments length\n",
+                                np->full_name);
+                       goto err1;
+               }
+next:
+               if (cur_index == index)
+                       break;
+
+               of_node_put(node);
+               node = NULL;
+               cur_index++;
+       }
+
+       if (!node) {
+               ret = -ENOENT;
+               goto err0;
+       }
+
+       *out_node = node;
+       *out_args = args;
+
+       return 0;
+err1:
+       of_node_put(node);
+err0:
+       pr_debug("%s failed with status %d\n", __func__, ret);
+       return ret;
+}
+EXPORT_SYMBOL(of_parse_phandles_with_args);
index 1c9cab844f10aaa60cf80d9996b4782d0c1256e6..7cd7301b583992683391215816bd6bd277785691 100644 (file)
  */
 int of_get_gpio(struct device_node *np, int index)
 {
-       int ret = -EINVAL;
+       int ret;
        struct device_node *gc;
        struct of_gpio_chip *of_gc = NULL;
        int size;
-       const u32 *gpios;
-       u32 nr_cells;
-       int i;
        const void *gpio_spec;
        const u32 *gpio_cells;
-       int gpio_index = 0;
 
-       gpios = of_get_property(np, "gpios", &size);
-       if (!gpios) {
-               ret = -ENOENT;
+       ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
+                                         &gc, &gpio_spec);
+       if (ret) {
+               pr_debug("%s: can't parse gpios property\n", __func__);
                goto err0;
        }
-       nr_cells = size / sizeof(u32);
-
-       for (i = 0; i < nr_cells; gpio_index++) {
-               const phandle *gpio_phandle;
-
-               gpio_phandle = gpios + i;
-               gpio_spec = gpio_phandle + 1;
-
-               /* one cell hole in the gpios = <>; */
-               if (!*gpio_phandle) {
-                       if (gpio_index == index)
-                               return -ENOENT;
-                       i++;
-                       continue;
-               }
-
-               gc = of_find_node_by_phandle(*gpio_phandle);
-               if (!gc) {
-                       pr_debug("%s: could not find phandle for gpios\n",
-                                np->full_name);
-                       goto err0;
-               }
-
-               of_gc = gc->data;
-               if (!of_gc) {
-                       pr_debug("%s: gpio controller %s isn't registered\n",
-                                np->full_name, gc->full_name);
-                       goto err1;
-               }
-
-               gpio_cells = of_get_property(gc, "#gpio-cells", &size);
-               if (!gpio_cells || size != sizeof(*gpio_cells) ||
-                               *gpio_cells != of_gc->gpio_cells) {
-                       pr_debug("%s: wrong #gpio-cells for %s\n",
-                                np->full_name, gc->full_name);
-                       goto err1;
-               }
-
-               /* Next phandle is at phandle cells + #gpio-cells */
-               i += sizeof(*gpio_phandle) / sizeof(u32) + *gpio_cells;
-               if (i >= nr_cells + 1) {
-                       pr_debug("%s: insufficient gpio-spec length\n",
-                                np->full_name);
-                       goto err1;
-               }
-
-               if (gpio_index == index)
-                       break;
-
-               of_gc = NULL;
-               of_node_put(gc);
-       }
 
+       of_gc = gc->data;
        if (!of_gc) {
-               ret = -ENOENT;
-               goto err0;
+               pr_debug("%s: gpio controller %s isn't registered\n",
+                        np->full_name, gc->full_name);
+               ret = -ENODEV;
+               goto err1;
+       }
+
+       gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+       if (!gpio_cells || size != sizeof(*gpio_cells) ||
+                       *gpio_cells != of_gc->gpio_cells) {
+               pr_debug("%s: wrong #gpio-cells for %s\n",
+                        np->full_name, gc->full_name);
+               ret = -EINVAL;
+               goto err1;
        }
 
        ret = of_gc->xlate(of_gc, np, gpio_spec);
index db717c1d62a5bd4f38952e2f9f441dde26ed6313..8565bbbeb6ecdf42f924366af7d96c7eeda24983 100644 (file)
        * ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd
        on timeout.  Matches 2.2.x behaviour.
 
-2001-03-02  Andrew Morton <andrewm@uow.edu.au>
+2001-03-02  Andrew Morton
 
        * parport_pc.c (registered_parport): New static variable.
        (parport_pc_find_ports): Set it when we register PCI driver.
index e97059415ab423387eb0dfd0f4c210cd38766c68..ac2a805ac7ea642e6bea96fc14bdcbe7a832b3c0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_ieee1284.c,v 1.4 1997/10/19 21:37:21 philip Exp $
+/*
  * IEEE-1284 implementation for parport.
  *
  * Authors: Phil Blundell <philb@gnu.org>
index cd565bb4e1a990ba303aa308a6094c7466b3e331..0f6550719bcf179d9fc493407b5d2a3dc38f447a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_probe.c,v 1.1 1999/07/03 08:56:17 davem Exp $
+/*
  * Parallel port device probing code
  *
  * Authors:    Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
index a8a62bbbb5769c61446386205c64266887793d5d..0ebca450ed298f6a79a4be0cc24fd71f8273532a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_share.c,v 1.15 1998/01/11 12:06:17 philip Exp $
+/*
  * Parallel-port resource manager code.
  * 
  * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
index 9b714ea93d207036fe9b51d6f3c2bbe0233c1c25..50884507b8be5005cd4767c65407edb7b4599db8 100644 (file)
@@ -147,9 +147,5 @@ int rpaphp_register_slot(struct slot *slot)
        list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
        info("Slot [%s] registered\n", slot->name);
        return 0;
-
-sysfs_fail:
-       pci_hp_deregister(php_slot);
-       return retval;
 }
 
index 36698e57b97f659dbc20f03f4f6df6fe0e718694..dd9161a054e1c1264891a918a634d5a60fa0d062 100644 (file)
@@ -1237,8 +1237,11 @@ EXPORT_SYMBOL(pci_scan_bridge);
 EXPORT_SYMBOL_GPL(pci_scan_child_bus);
 #endif
 
-static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b)
+static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
 {
+       const struct pci_dev *a = to_pci_dev(d_a);
+       const struct pci_dev *b = to_pci_dev(d_b);
+
        if      (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1;
        else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return  1;
 
@@ -1251,50 +1254,7 @@ static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev
        return 0;
 }
 
-/*
- * Yes, this forcably breaks the klist abstraction temporarily.  It
- * just wants to sort the klist, not change reference counts and
- * take/drop locks rapidly in the process.  It does all this while
- * holding the lock for the list, so objects can't otherwise be
- * added/removed while we're swizzling.
- */
-static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list)
-{
-       struct list_head *pos;
-       struct klist_node *n;
-       struct device *dev;
-       struct pci_dev *b;
-
-       list_for_each(pos, list) {
-               n = container_of(pos, struct klist_node, n_node);
-               dev = container_of(n, struct device, knode_bus);
-               b = to_pci_dev(dev);
-               if (pci_sort_bf_cmp(a, b) <= 0) {
-                       list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node);
-                       return;
-               }
-       }
-       list_move_tail(&a->dev.knode_bus.n_node, list);
-}
-
 void __init pci_sort_breadthfirst(void)
 {
-       LIST_HEAD(sorted_devices);
-       struct list_head *pos, *tmp;
-       struct klist_node *n;
-       struct device *dev;
-       struct pci_dev *pdev;
-       struct klist *device_klist;
-
-       device_klist = bus_get_device_klist(&pci_bus_type);
-
-       spin_lock(&device_klist->k_lock);
-       list_for_each_safe(pos, tmp, &device_klist->k_list) {
-               n = container_of(pos, struct klist_node, n_node);
-               dev = container_of(n, struct device, knode_bus);
-               pdev = to_pci_dev(dev);
-               pci_insertion_sort_klist(pdev, &sorted_devices);
-       }
-       list_splice(&sorted_devices, &device_klist->k_list);
-       spin_unlock(&device_klist->k_lock);
+       bus_sort_breadthfirst(&pci_bus_type, &pci_sort_bf_cmp);
 }
index 74d1c906c5d6f61cff812db070ac3bda68e19299..b46c60b7270842fcbaef50f7bd9eb8136e0d50f0 100644 (file)
@@ -64,10 +64,11 @@ sa1100_cs-$(CONFIG_SA1100_SHANNON)          += sa1100_shannon.o
 sa1100_cs-$(CONFIG_SA1100_SIMPAD)              += sa1100_simpad.o
 
 pxa2xx_lubbock_cs-y                            += pxa2xx_lubbock.o sa1111_generic.o
+pxa2xx_cm_x2xx_cs-y                            += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
 pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK)              += pxa2xx_lubbock_cs.o
 pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)            += pxa2xx_mainstone.o
 pxa2xx-obj-$(CONFIG_PXA_SHARPSL)               += pxa2xx_sharpsl.o
-pxa2xx-obj-$(CONFIG_MACH_ARMCORE)              += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
+pxa2xx-obj-$(CONFIG_MACH_ARMCORE)              += pxa2xx_cm_x2xx_cs.o
 pxa2xx-obj-$(CONFIG_ARCH_VIPER)                        += pxa2xx_viper.o
 pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)            += pxa2xx_trizeps.o
 pxa2xx-obj-$(CONFIG_MACH_PALMTX)               += pxa2xx_palmtx.o
index 9fd7bb9b7dce2579d1955a055ad5bf362f0e14b2..3b8b9d3cb03d6cc2f8738e67abd145ff09a4285f 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 extern spinlock_t pnp_lock;
+extern struct device_attribute pnp_interface_attrs[];
 void *pnp_alloc(long size);
 
 int pnp_register_protocol(struct pnp_protocol *protocol);
@@ -16,7 +17,6 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
 
 int pnp_add_device(struct pnp_dev *dev);
 struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
-int pnp_interface_attach_device(struct pnp_dev *dev);
 
 int pnp_add_card(struct pnp_card *card);
 void pnp_remove_card(struct pnp_card *card);
@@ -147,7 +147,7 @@ char *pnp_resource_type_name(struct resource *res);
 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
 
 void pnp_free_resources(struct pnp_dev *dev);
-int pnp_resource_type(struct resource *res);
+unsigned long pnp_resource_type(struct resource *res);
 
 struct pnp_resource {
        struct list_head list;
index a411582bcd72d3caf7638fc1ede2a0747498af6e..817fe626e15b2d78a5cfa32ab7f26e761ee37009 100644 (file)
@@ -159,21 +159,13 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
 
 int __pnp_add_device(struct pnp_dev *dev)
 {
-       int ret;
-
        pnp_fixup_device(dev);
        dev->status = PNP_READY;
        spin_lock(&pnp_lock);
        list_add_tail(&dev->global_list, &pnp_global);
        list_add_tail(&dev->protocol_list, &dev->protocol->devices);
        spin_unlock(&pnp_lock);
-
-       ret = device_register(&dev->dev);
-       if (ret)
-               return ret;
-
-       pnp_interface_attach_device(dev);
-       return 0;
+       return device_register(&dev->dev);
 }
 
 /*
@@ -218,7 +210,6 @@ void __pnp_remove_device(struct pnp_dev *dev)
 
 static int __init pnp_init(void)
 {
-       printk(KERN_INFO "Linux Plug and Play Support v0.97 (c) Adam Belay\n");
        return bus_register(&pnp_bus_type);
 }
 
index d3f869ee1d92a5b8e90919b6df880efb7ec73ee8..e3f7e89c4dfb29a794a86a40a8bcf088550c032f 100644 (file)
@@ -206,6 +206,7 @@ struct bus_type pnp_bus_type = {
        .remove  = pnp_device_remove,
        .suspend = pnp_bus_suspend,
        .resume  = pnp_bus_resume,
+       .dev_attrs = pnp_interface_attrs,
 };
 
 int pnp_register_driver(struct pnp_driver *drv)
index a876ecf7028c06c003d5fc1aed974bb9f5f97f98..478a4a739c00dabdc3ccf3a4689b2e84c32d5ce6 100644 (file)
@@ -243,8 +243,6 @@ static ssize_t pnp_show_options(struct device *dmdev,
        return ret;
 }
 
-static DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL);
-
 static ssize_t pnp_show_current_resources(struct device *dmdev,
                                          struct device_attribute *attr,
                                          char *buf)
@@ -420,9 +418,6 @@ done:
        return count;
 }
 
-static DEVICE_ATTR(resources, S_IRUGO | S_IWUSR,
-                  pnp_show_current_resources, pnp_set_current_resources);
-
 static ssize_t pnp_show_current_ids(struct device *dmdev,
                                    struct device_attribute *attr, char *buf)
 {
@@ -437,27 +432,11 @@ static ssize_t pnp_show_current_ids(struct device *dmdev,
        return (str - buf);
 }
 
-static DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL);
-
-int pnp_interface_attach_device(struct pnp_dev *dev)
-{
-       int rc = device_create_file(&dev->dev, &dev_attr_options);
-
-       if (rc)
-               goto err;
-       rc = device_create_file(&dev->dev, &dev_attr_resources);
-       if (rc)
-               goto err_opt;
-       rc = device_create_file(&dev->dev, &dev_attr_id);
-       if (rc)
-               goto err_res;
-
-       return 0;
-
-err_res:
-       device_remove_file(&dev->dev, &dev_attr_resources);
-err_opt:
-       device_remove_file(&dev->dev, &dev_attr_options);
-err:
-       return rc;
-}
+struct device_attribute pnp_interface_attrs[] = {
+       __ATTR(resources, S_IRUGO | S_IWUSR,
+                  pnp_show_current_resources,
+                  pnp_set_current_resources),
+       __ATTR(options, S_IRUGO, pnp_show_options, NULL),
+       __ATTR(id, S_IRUGO, pnp_show_current_ids, NULL),
+       __ATTR_NULL,
+};
index 101a835e8759fb3f757d72426cfc05c2d678865c..46455fbab6d51f6dae89b6b68da5a4b2f34f4851 100644 (file)
@@ -1012,7 +1012,7 @@ static int __init isapnp_init(void)
                printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
                return 0;
        }
-#ifdef CONFIG_PPC_MERGE
+#ifdef CONFIG_PPC
        if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
                return -EINVAL;
 #endif
index 662dfcddedc62fce03362f72cd79c421f6542a37..2bfe13369df5e75d36d58bb1674646bc424bcfac 100644 (file)
@@ -519,7 +519,7 @@ static int __init pnpbios_init(void)
 {
        int ret;
 
-#if defined(CONFIG_PPC_MERGE)
+#if defined(CONFIG_PPC)
        if (check_legacy_ioport(PNPBIOS_BASE))
                return -ENODEV;
 #endif
@@ -577,7 +577,7 @@ static int __init pnpbios_thread_init(void)
 {
        struct task_struct *task;
 
-#if defined(CONFIG_PPC_MERGE)
+#if defined(CONFIG_PPC)
        if (check_legacy_ioport(PNPBIOS_BASE))
                return 0;
 #endif
index 0bdf9b8a5e58593d308ecc95f25fb7d2209e2998..d15e2b77af889fda464c269dc10ce919504bcfe7 100644 (file)
@@ -245,7 +245,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
         */
        for_each_pci_dev(pdev) {
                for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       unsigned int type;
+                       unsigned long type;
 
                        type = pci_resource_flags(pdev, i) &
                                        (IORESOURCE_IO | IORESOURCE_MEM);
index 4cfe3a1efdfbc24a213abc838dab1631abf9f5d4..dbae23acdd5b12e1df4a83164dbec01a4c6d7a54 100644 (file)
@@ -467,14 +467,14 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
 #endif
 }
 
-int pnp_resource_type(struct resource *res)
+unsigned long pnp_resource_type(struct resource *res)
 {
        return res->flags & (IORESOURCE_IO  | IORESOURCE_MEM |
                             IORESOURCE_IRQ | IORESOURCE_DMA);
 }
 
 struct resource *pnp_get_resource(struct pnp_dev *dev,
-                                 unsigned int type, unsigned int num)
+                                 unsigned long type, unsigned int num)
 {
        struct pnp_resource *pnp_res;
        struct resource *res;
index 32570af3c5c904fa86cffe26efbcc7650757d474..5fbca2681baaeb112ef0ae789ddd6aabb2a63156 100644 (file)
@@ -205,9 +205,9 @@ static int olpc_bat_get_property(struct power_supply *psy,
                                 union power_supply_propval *val)
 {
        int ret = 0;
-       int16_t ec_word;
+       __be16 ec_word;
        uint8_t ec_byte;
-       uint64_t ser_buf;
+       __be64 ser_buf;
 
        ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
        if (ret)
@@ -257,16 +257,14 @@ static int olpc_bat_get_property(struct power_supply *psy,
                if (ret)
                        return ret;
 
-               ec_word = be16_to_cpu(ec_word);
-               val->intval = ec_word * 9760L / 32;
+               val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32;
                break;
        case POWER_SUPPLY_PROP_CURRENT_AVG:
                ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
                if (ret)
                        return ret;
 
-               ec_word = be16_to_cpu(ec_word);
-               val->intval = ec_word * 15625L / 120;
+               val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120;
                break;
        case POWER_SUPPLY_PROP_CAPACITY:
                ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
@@ -278,24 +276,22 @@ static int olpc_bat_get_property(struct power_supply *psy,
                ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
                if (ret)
                        return ret;
-               ec_word = be16_to_cpu(ec_word);
-               val->intval = ec_word * 100 / 256;
+
+               val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
                break;
        case POWER_SUPPLY_PROP_TEMP_AMBIENT:
                ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
                if (ret)
                        return ret;
 
-               ec_word = be16_to_cpu(ec_word);
-               val->intval = ec_word * 100 / 256;
+               val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
                break;
        case POWER_SUPPLY_PROP_CHARGE_COUNTER:
                ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2);
                if (ret)
                        return ret;
 
-               ec_word = be16_to_cpu(ec_word);
-               val->intval = ec_word * 6250 / 15;
+               val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15;
                break;
        case POWER_SUPPLY_PROP_SERIAL_NUMBER:
                ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8);
index cb1ccb4729210c1a3cfd8901bf7dea5c56117146..3007695f90c822e067a31e3c44da67d4598ff2e7 100644 (file)
@@ -91,8 +91,8 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
 {
        int rc = 0;
 
-       psy->dev = device_create_drvdata(power_supply_class, parent, 0,
-                                        psy, "%s", psy->name);
+       psy->dev = device_create(power_supply_class, parent, 0, psy,
+                                "%s", psy->name);
        if (IS_ERR(psy->dev)) {
                rc = PTR_ERR(psy->dev);
                goto dev_create_failed;
index b57fba5c6d027d645573ae070649d745bab26950..f660ef3e5b29e801f205eb06358cf54f26490e25 100644 (file)
@@ -220,22 +220,22 @@ config RTC_DRV_PCF8583
          will be called rtc-pcf8583.
 
 config RTC_DRV_M41T80
-       tristate "ST M41T80/81/82/83/84/85/87"
+       tristate "ST M41T65/M41T80/81/82/83/84/85/87"
        help
-         If you say Y here you will get support for the
-         ST M41T80 RTC chips series. Currently following chips are
-         supported: M41T80, M41T81, M41T82, M41T83, M41ST84, M41ST85
-         and M41ST87.
+         If you say Y here you will get support for the ST M41T60
+         and M41T80 RTC chips series. Currently, the following chips are
+         supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
+         M41ST85, and M41ST87.
 
          This driver can also be built as a module. If so, the module
          will be called rtc-m41t80.
 
 config RTC_DRV_M41T80_WDT
-       bool "ST M41T80 series RTC watchdog timer"
+       bool "ST M41T65/M41T80 series RTC watchdog timer"
        depends on RTC_DRV_M41T80
        help
          If you say Y here you will get support for the
-         watchdog timer in ST M41T80 RTC chips series.
+         watchdog timer in the ST M41T60 and M41T80 RTC chips series.
 
 config RTC_DRV_TWL92330
        boolean "TI TWL92330/Menelaus"
@@ -319,6 +319,15 @@ config RTC_DRV_RS5C348
          This driver can also be built as a module. If so, the module
          will be called rtc-rs5c348.
 
+config RTC_DRV_DS3234
+       tristate "Maxim/Dallas DS3234"
+       help
+         If you say yes here you get support for the
+         Maxim/Dallas DS3234 SPI RTC chip.
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-ds3234.
+
 endif # SPI_MASTER
 
 comment "Platform RTC drivers"
@@ -352,6 +361,11 @@ config RTC_DRV_DS1216
        help
          If you say yes here you get support for the Dallas DS1216 RTC chips.
 
+config RTC_DRV_DS1286
+       tristate "Dallas DS1286"
+       help
+         If you say yes here you get support for the Dallas DS1286 RTC chips.
+
 config RTC_DRV_DS1302
        tristate "Dallas DS1302"
        depends on SH_SECUREEDGE5410
@@ -405,6 +419,15 @@ config RTC_DRV_M48T86
          This driver can also be built as a module. If so, the module
          will be called rtc-m48t86.
 
+config RTC_DRV_M48T35
+       tristate "ST M48T35"
+       help
+         If you say Y here you will get support for the
+         ST M48T35 RTC chip.
+
+         This driver can also be built as a module, if so, the module
+         will be called "rtc-m48t35".
+
 config RTC_DRV_M48T59
        tristate "ST M48T59/M48T08/M48T02"
        help
@@ -589,7 +612,7 @@ config RTC_DRV_RS5C313
 
 config RTC_DRV_PPC
        tristate "PowerPC machine dependent RTC support"
-       depends on PPC_MERGE
+       depends on PPC
        help
         The PowerPC kernel has machine-specific functions for accessing
         the RTC. This exposes that functionality through the generic RTC
index 10f41f85c38a0fbbea375e7d38b5ef1ea3a805a1..d05928b3ca9466b7402a2392f555e32f3051ad31 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9)        += rtc-at91sam9.o
 obj-$(CONFIG_RTC_DRV_BFIN)     += rtc-bfin.o
 obj-$(CONFIG_RTC_DRV_CMOS)     += rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_DS1216)   += rtc-ds1216.o
+obj-$(CONFIG_RTC_DRV_DS1286)   += rtc-ds1286.o
 obj-$(CONFIG_RTC_DRV_DS1302)   += rtc-ds1302.o
 obj-$(CONFIG_RTC_DRV_DS1305)   += rtc-ds1305.o
 obj-$(CONFIG_RTC_DRV_DS1307)   += rtc-ds1307.o
@@ -31,11 +32,13 @@ obj-$(CONFIG_RTC_DRV_DS1511)        += rtc-ds1511.o
 obj-$(CONFIG_RTC_DRV_DS1553)   += rtc-ds1553.o
 obj-$(CONFIG_RTC_DRV_DS1672)   += rtc-ds1672.o
 obj-$(CONFIG_RTC_DRV_DS1742)   += rtc-ds1742.o
+obj-$(CONFIG_RTC_DRV_DS3234)   += rtc-ds3234.o
 obj-$(CONFIG_RTC_DRV_EP93XX)   += rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_FM3130)   += rtc-fm3130.o
 obj-$(CONFIG_RTC_DRV_ISL1208)  += rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_M41T80)   += rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M41T94)   += rtc-m41t94.o
+obj-$(CONFIG_RTC_DRV_M48T35)   += rtc-m48t35.o
 obj-$(CONFIG_RTC_DRV_M48T59)   += rtc-m48t59.o
 obj-$(CONFIG_RTC_DRV_M48T86)   += rtc-m48t86.o
 obj-$(CONFIG_RTC_DRV_BQ4802)   += rtc-bq4802.o
index 4e888cc8be5b1cacbeac68bd054ab3f6f65d295a..37082616482bd7a79ad3162ba00ca82bd260894e 100644 (file)
 #include <linux/completion.h>
 
 #include <asm/uaccess.h>
+
 #include <mach/at91_rtc.h>
 
 
-#define AT91_RTC_FREQ          1
 #define AT91_RTC_EPOCH         1900UL  /* just like arch/arm/common/rtctime.c */
 
 static DECLARE_COMPLETION(at91_rtc_updated);
@@ -228,8 +228,6 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
                        (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
        seq_printf(seq, "periodic_IRQ\t: %s\n",
                        (imr & AT91_RTC_SECEV) ? "yes" : "no");
-       seq_printf(seq, "periodic_freq\t: %ld\n",
-                       (unsigned long) AT91_RTC_FREQ);
 
        return 0;
 }
index 52e2743b04ecf77bb6a975d6c8609fa042025dea..079e9ed907e06caa6d5a453c56c31e413f0cf6c5 100644 (file)
@@ -432,9 +432,15 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
 {
        struct rtc_device *rtc = file->private_data;
 
-#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
-       clear_uie(rtc);
-#endif
+       /* We shut down the repeating IRQs that userspace enabled,
+        * since nothing is listening to them.
+        *  - Update (UIE) ... currently only managed through ioctls
+        *  - Periodic (PIE) ... also used through rtc_*() interface calls
+        *
+        * Leave the alarm alone; it may be set to trigger a system wakeup
+        * later, or be used by kernel code, and is a one-shot event anyway.
+        */
+       rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
        rtc_irq_set_state(rtc, NULL, 0);
 
        if (rtc->ops->release)
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
new file mode 100644 (file)
index 0000000..4fcb16b
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * DS1286 Real Time Clock interface for Linux
+ *
+ * Copyright (C) 1998, 1999, 2000 Ralf Baechle
+ * Copyright (C) 2008 Thomas Bogendoerfer
+ *
+ * Based on code written by Paul Gortmaker.
+ *
+ * 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/module.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/bcd.h>
+#include <linux/ds1286.h>
+#include <linux/io.h>
+
+#define DRV_VERSION            "1.0"
+
+struct ds1286_priv {
+       struct rtc_device *rtc;
+       u32 __iomem *rtcregs;
+       size_t size;
+       unsigned long baseaddr;
+       spinlock_t lock;
+};
+
+static inline u8 ds1286_rtc_read(struct ds1286_priv *priv, int reg)
+{
+       return __raw_readl(&priv->rtcregs[reg]) & 0xff;
+}
+
+static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg)
+{
+       __raw_writel(data, &priv->rtcregs[reg]);
+}
+
+#ifdef CONFIG_RTC_INTF_DEV
+
+static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned long flags;
+       unsigned char val;
+
+       switch (cmd) {
+       case RTC_AIE_OFF:
+               /* Mask alarm int. enab. bit    */
+               spin_lock_irqsave(&priv->lock, flags);
+               val = ds1286_rtc_read(priv, RTC_CMD);
+               val |=  RTC_TDM;
+               ds1286_rtc_write(priv, val, RTC_CMD);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               break;
+       case RTC_AIE_ON:
+               /* Allow alarm interrupts.      */
+               spin_lock_irqsave(&priv->lock, flags);
+               val = ds1286_rtc_read(priv, RTC_CMD);
+               val &=  ~RTC_TDM;
+               ds1286_rtc_write(priv, val, RTC_CMD);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               break;
+       case RTC_WIE_OFF:
+               /* Mask watchdog int. enab. bit */
+               spin_lock_irqsave(&priv->lock, flags);
+               val = ds1286_rtc_read(priv, RTC_CMD);
+               val |= RTC_WAM;
+               ds1286_rtc_write(priv, val, RTC_CMD);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               break;
+       case RTC_WIE_ON:
+               /* Allow watchdog interrupts.   */
+               spin_lock_irqsave(&priv->lock, flags);
+               val = ds1286_rtc_read(priv, RTC_CMD);
+               val &= ~RTC_WAM;
+               ds1286_rtc_write(priv, val, RTC_CMD);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               break;
+       default:
+               return -ENOIOCTLCMD;
+       }
+       return 0;
+}
+
+#else
+#define ds1286_ioctl    NULL
+#endif
+
+#ifdef CONFIG_PROC_FS
+
+static int ds1286_proc(struct device *dev, struct seq_file *seq)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned char month, cmd, amode;
+       const char *s;
+
+       month = ds1286_rtc_read(priv, RTC_MONTH);
+       seq_printf(seq,
+                  "oscillator\t: %s\n"
+                  "square_wave\t: %s\n",
+                  (month & RTC_EOSC) ? "disabled" : "enabled",
+                  (month & RTC_ESQW) ? "disabled" : "enabled");
+
+       amode = ((ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x80) >> 5) |
+               ((ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x80) >> 6) |
+               ((ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x80) >> 7);
+       switch (amode) {
+       case 7:
+               s = "each minute";
+               break;
+       case 3:
+               s = "minutes match";
+               break;
+       case 1:
+               s = "hours and minutes match";
+               break;
+       case 0:
+               s = "days, hours and minutes match";
+               break;
+       default:
+               s = "invalid";
+               break;
+       }
+       seq_printf(seq, "alarm_mode\t: %s\n", s);
+
+       cmd = ds1286_rtc_read(priv, RTC_CMD);
+       seq_printf(seq,
+                  "alarm_enable\t: %s\n"
+                  "wdog_alarm\t: %s\n"
+                  "alarm_mask\t: %s\n"
+                  "wdog_alarm_mask\t: %s\n"
+                  "interrupt_mode\t: %s\n"
+                  "INTB_mode\t: %s_active\n"
+                  "interrupt_pins\t: %s\n",
+                  (cmd & RTC_TDF) ? "yes" : "no",
+                  (cmd & RTC_WAF) ? "yes" : "no",
+                  (cmd & RTC_TDM) ? "disabled" : "enabled",
+                  (cmd & RTC_WAM) ? "disabled" : "enabled",
+                  (cmd & RTC_PU_LVL) ? "pulse" : "level",
+                  (cmd & RTC_IBH_LO) ? "low" : "high",
+                  (cmd & RTC_IPSW) ? "unswapped" : "swapped");
+       return 0;
+}
+
+#else
+#define ds1286_proc     NULL
+#endif
+
+static int ds1286_read_time(struct device *dev, struct rtc_time *tm)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned char save_control;
+       unsigned long flags;
+       unsigned long uip_watchdog = jiffies;
+
+       /*
+        * read RTC once any update in progress is done. The update
+        * can take just over 2ms. We wait 10 to 20ms. There is no need to
+        * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
+        * If you need to know *exactly* when a second has started, enable
+        * periodic update complete interrupts, (via ioctl) and then
+        * immediately read /dev/rtc which will block until you get the IRQ.
+        * Once the read clears, read the RTC time (again via ioctl). Easy.
+        */
+
+       if (ds1286_rtc_read(priv, RTC_CMD) & RTC_TE)
+               while (time_before(jiffies, uip_watchdog + 2*HZ/100))
+                       barrier();
+
+       /*
+        * Only the values that we read from the RTC are set. We leave
+        * tm_wday, tm_yday and tm_isdst untouched. Even though the
+        * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
+        * by the RTC when initially set to a non-zero value.
+        */
+       spin_lock_irqsave(&priv->lock, flags);
+       save_control = ds1286_rtc_read(priv, RTC_CMD);
+       ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD);
+
+       tm->tm_sec = ds1286_rtc_read(priv, RTC_SECONDS);
+       tm->tm_min = ds1286_rtc_read(priv, RTC_MINUTES);
+       tm->tm_hour = ds1286_rtc_read(priv, RTC_HOURS) & 0x3f;
+       tm->tm_mday = ds1286_rtc_read(priv, RTC_DATE);
+       tm->tm_mon = ds1286_rtc_read(priv, RTC_MONTH) & 0x1f;
+       tm->tm_year = ds1286_rtc_read(priv, RTC_YEAR);
+
+       ds1286_rtc_write(priv, save_control, RTC_CMD);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       tm->tm_sec = bcd2bin(tm->tm_sec);
+       tm->tm_min = bcd2bin(tm->tm_min);
+       tm->tm_hour = bcd2bin(tm->tm_hour);
+       tm->tm_mday = bcd2bin(tm->tm_mday);
+       tm->tm_mon = bcd2bin(tm->tm_mon);
+       tm->tm_year = bcd2bin(tm->tm_year);
+
+       /*
+        * Account for differences between how the RTC uses the values
+        * and how they are defined in a struct rtc_time;
+        */
+       if (tm->tm_year < 45)
+               tm->tm_year += 30;
+       tm->tm_year += 40;
+       if (tm->tm_year < 70)
+               tm->tm_year += 100;
+
+       tm->tm_mon--;
+
+       return rtc_valid_tm(tm);
+}
+
+static int ds1286_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned char mon, day, hrs, min, sec;
+       unsigned char save_control;
+       unsigned int yrs;
+       unsigned long flags;
+
+       yrs = tm->tm_year + 1900;
+       mon = tm->tm_mon + 1;   /* tm_mon starts at zero */
+       day = tm->tm_mday;
+       hrs = tm->tm_hour;
+       min = tm->tm_min;
+       sec = tm->tm_sec;
+
+       if (yrs < 1970)
+               return -EINVAL;
+
+       yrs -= 1940;
+       if (yrs > 255)    /* They are unsigned */
+               return -EINVAL;
+
+       if (yrs >= 100)
+               yrs -= 100;
+
+       sec = bin2bcd(sec);
+       min = bin2bcd(min);
+       hrs = bin2bcd(hrs);
+       day = bin2bcd(day);
+       mon = bin2bcd(mon);
+       yrs = bin2bcd(yrs);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       save_control = ds1286_rtc_read(priv, RTC_CMD);
+       ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD);
+
+       ds1286_rtc_write(priv, yrs, RTC_YEAR);
+       ds1286_rtc_write(priv, mon, RTC_MONTH);
+       ds1286_rtc_write(priv, day, RTC_DATE);
+       ds1286_rtc_write(priv, hrs, RTC_HOURS);
+       ds1286_rtc_write(priv, min, RTC_MINUTES);
+       ds1286_rtc_write(priv, sec, RTC_SECONDS);
+       ds1286_rtc_write(priv, 0, RTC_HUNDREDTH_SECOND);
+
+       ds1286_rtc_write(priv, save_control, RTC_CMD);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return 0;
+}
+
+static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned char cmd;
+       unsigned long flags;
+
+       /*
+        * Only the values that we read from the RTC are set. That
+        * means only tm_wday, tm_hour, tm_min.
+        */
+       spin_lock_irqsave(&priv->lock, flags);
+       alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f;
+       alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM)  & 0x1f;
+       alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM)    & 0x07;
+       cmd = ds1286_rtc_read(priv, RTC_CMD);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       alm->time.tm_min = bcd2bin(alm->time.tm_min);
+       alm->time.tm_hour = bcd2bin(alm->time.tm_hour);
+       alm->time.tm_sec = 0;
+       return 0;
+}
+
+static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned char hrs, min, sec;
+
+       hrs = alm->time.tm_hour;
+       min = alm->time.tm_min;
+       sec = alm->time.tm_sec;
+
+       if (hrs >= 24)
+               hrs = 0xff;
+
+       if (min >= 60)
+               min = 0xff;
+
+       if (sec != 0)
+               return -EINVAL;
+
+       min = bin2bcd(min);
+       hrs = bin2bcd(hrs);
+
+       spin_lock(&priv->lock);
+       ds1286_rtc_write(priv, hrs, RTC_HOURS_ALARM);
+       ds1286_rtc_write(priv, min, RTC_MINUTES_ALARM);
+       spin_unlock(&priv->lock);
+
+       return 0;
+}
+
+static const struct rtc_class_ops ds1286_ops = {
+       .ioctl          = ds1286_ioctl,
+       .proc           = ds1286_proc,
+       .read_time      = ds1286_read_time,
+       .set_time       = ds1286_set_time,
+       .read_alarm     = ds1286_read_alarm,
+       .set_alarm      = ds1286_set_alarm,
+};
+
+static int __devinit ds1286_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtc;
+       struct resource *res;
+       struct ds1286_priv *priv;
+       int ret = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+       priv = kzalloc(sizeof(struct ds1286_priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->size = res->end - res->start + 1;
+       if (!request_mem_region(res->start, priv->size, pdev->name)) {
+               ret = -EBUSY;
+               goto out;
+       }
+       priv->baseaddr = res->start;
+       priv->rtcregs = ioremap(priv->baseaddr, priv->size);
+       if (!priv->rtcregs) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       spin_lock_init(&priv->lock);
+       rtc = rtc_device_register("ds1286", &pdev->dev,
+                                 &ds1286_ops, THIS_MODULE);
+       if (IS_ERR(rtc)) {
+               ret = PTR_ERR(rtc);
+               goto out;
+       }
+       priv->rtc = rtc;
+       platform_set_drvdata(pdev, priv);
+       return 0;
+
+out:
+       if (priv->rtc)
+               rtc_device_unregister(priv->rtc);
+       if (priv->rtcregs)
+               iounmap(priv->rtcregs);
+       if (priv->baseaddr)
+               release_mem_region(priv->baseaddr, priv->size);
+       kfree(priv);
+       return ret;
+}
+
+static int __devexit ds1286_remove(struct platform_device *pdev)
+{
+       struct ds1286_priv *priv = platform_get_drvdata(pdev);
+
+       rtc_device_unregister(priv->rtc);
+       iounmap(priv->rtcregs);
+       release_mem_region(priv->baseaddr, priv->size);
+       kfree(priv);
+       return 0;
+}
+
+static struct platform_driver ds1286_platform_driver = {
+       .driver         = {
+               .name   = "rtc-ds1286",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = ds1286_probe,
+       .remove         = __devexit_p(ds1286_remove),
+};
+
+static int __init ds1286_init(void)
+{
+       return platform_driver_register(&ds1286_platform_driver);
+}
+
+static void __exit ds1286_exit(void)
+{
+       platform_driver_unregister(&ds1286_platform_driver);
+}
+
+MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
+MODULE_DESCRIPTION("DS1286 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:rtc-ds1286");
+
+module_init(ds1286_init);
+module_exit(ds1286_exit);
index bbf97e65202a24327b57beafbba98d6daca738a2..4fcf0734a6ef088f5bf162de0f09341bac979349 100644 (file)
  * to have set the chip up as a clock (turning on the oscillator and
  * setting the date and time), Linux can ignore the non-clock features.
  * That's a natural job for a factory or repair bench.
- *
- * This is currently a simple no-alarms driver.  If your board has the
- * alarm irq wired up on a ds1337 or ds1339, and you want to use that,
- * then look at the rtc-rs5c372 driver for code to steal...
  */
 enum ds_type {
        ds_1307,
@@ -67,6 +63,7 @@ enum ds_type {
 #      define DS1307_BIT_RS0           0x01
 #define DS1337_REG_CONTROL     0x0e
 #      define DS1337_BIT_nEOSC         0x80
+#      define DS1339_BIT_BBSQI         0x20
 #      define DS1337_BIT_RS2           0x10
 #      define DS1337_BIT_RS1           0x08
 #      define DS1337_BIT_INTCN         0x04
@@ -83,19 +80,22 @@ enum ds_type {
 #      define DS1337_BIT_OSF           0x80
 #      define DS1337_BIT_A2I           0x02
 #      define DS1337_BIT_A1I           0x01
+#define DS1339_REG_ALARM1_SECS 0x07
 #define DS1339_REG_TRICKLE     0x10
 
 
 
 struct ds1307 {
        u8                      reg_addr;
-       bool                    has_nvram;
-       u8                      regs[8];
+       u8                      regs[11];
        enum ds_type            type;
+       unsigned long           flags;
+#define HAS_NVRAM      0               /* bit 0 == sysfs file active */
+#define HAS_ALARM      1               /* bit 1 == irq claimed */
        struct i2c_msg          msg[2];
        struct i2c_client       *client;
-       struct i2c_client       dev;
        struct rtc_device       *rtc;
+       struct work_struct      work;
 };
 
 struct chip_desc {
@@ -132,12 +132,79 @@ static const struct i2c_device_id ds1307_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, ds1307_id);
 
+/*----------------------------------------------------------------------*/
+
+/*
+ * The IRQ logic includes a "real" handler running in IRQ context just
+ * long enough to schedule this workqueue entry.   We need a task context
+ * to talk to the RTC, since I2C I/O calls require that; and disable the
+ * IRQ until we clear its status on the chip, so that this handler can
+ * work with any type of triggering (not just falling edge).
+ *
+ * The ds1337 and ds1339 both have two alarms, but we only use the first
+ * one (with a "seconds" field).  For ds1337 we expect nINTA is our alarm
+ * signal; ds1339 chips have only one alarm signal.
+ */
+static void ds1307_work(struct work_struct *work)
+{
+       struct ds1307           *ds1307;
+       struct i2c_client       *client;
+       struct mutex            *lock;
+       int                     stat, control;
+
+       ds1307 = container_of(work, struct ds1307, work);
+       client = ds1307->client;
+       lock = &ds1307->rtc->ops_lock;
+
+       mutex_lock(lock);
+       stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
+       if (stat < 0)
+               goto out;
+
+       if (stat & DS1337_BIT_A1I) {
+               stat &= ~DS1337_BIT_A1I;
+               i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, stat);
+
+               control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+               if (control < 0)
+                       goto out;
+
+               control &= ~DS1337_BIT_A1IE;
+               i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control);
+
+               /* rtc_update_irq() assumes that it is called
+                * from IRQ-disabled context.
+                */
+               local_irq_disable();
+               rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
+               local_irq_enable();
+       }
+
+out:
+       if (test_bit(HAS_ALARM, &ds1307->flags))
+               enable_irq(client->irq);
+       mutex_unlock(lock);
+}
+
+static irqreturn_t ds1307_irq(int irq, void *dev_id)
+{
+       struct i2c_client       *client = dev_id;
+       struct ds1307           *ds1307 = i2c_get_clientdata(client);
+
+       disable_irq_nosync(irq);
+       schedule_work(&ds1307->work);
+       return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
 static int ds1307_get_time(struct device *dev, struct rtc_time *t)
 {
        struct ds1307   *ds1307 = dev_get_drvdata(dev);
        int             tmp;
 
        /* read the RTC date and time registers all at once */
+       ds1307->reg_addr = 0;
        ds1307->msg[1].flags = I2C_M_RD;
        ds1307->msg[1].len = 7;
 
@@ -231,9 +298,186 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
        return 0;
 }
 
+static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct ds1307           *ds1307 = i2c_get_clientdata(client);
+       int                     ret;
+
+       if (!test_bit(HAS_ALARM, &ds1307->flags))
+               return -EINVAL;
+
+       /* read all ALARM1, ALARM2, and status registers at once */
+       ds1307->reg_addr = DS1339_REG_ALARM1_SECS;
+       ds1307->msg[1].flags = I2C_M_RD;
+       ds1307->msg[1].len = 9;
+
+       ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
+                       ds1307->msg, 2);
+       if (ret != 2) {
+               dev_err(dev, "%s error %d\n", "alarm read", ret);
+               return -EIO;
+       }
+
+       dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
+                       "alarm read",
+                       ds1307->regs[0], ds1307->regs[1],
+                       ds1307->regs[2], ds1307->regs[3],
+                       ds1307->regs[4], ds1307->regs[5],
+                       ds1307->regs[6], ds1307->regs[7],
+                       ds1307->regs[8]);
+
+       /* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
+        * and that all four fields are checked matches
+        */
+       t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
+       t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
+       t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
+       t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
+       t->time.tm_mon = -1;
+       t->time.tm_year = -1;
+       t->time.tm_wday = -1;
+       t->time.tm_yday = -1;
+       t->time.tm_isdst = -1;
+
+       /* ... and status */
+       t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
+       t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
+
+       dev_dbg(dev, "%s secs=%d, mins=%d, "
+               "hours=%d, mday=%d, enabled=%d, pending=%d\n",
+               "alarm read", t->time.tm_sec, t->time.tm_min,
+               t->time.tm_hour, t->time.tm_mday,
+               t->enabled, t->pending);
+
+       return 0;
+}
+
+static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct ds1307           *ds1307 = i2c_get_clientdata(client);
+       unsigned char           *buf = ds1307->regs;
+       u8                      control, status;
+       int                     ret;
+
+       if (!test_bit(HAS_ALARM, &ds1307->flags))
+               return -EINVAL;
+
+       dev_dbg(dev, "%s secs=%d, mins=%d, "
+               "hours=%d, mday=%d, enabled=%d, pending=%d\n",
+               "alarm set", t->time.tm_sec, t->time.tm_min,
+               t->time.tm_hour, t->time.tm_mday,
+               t->enabled, t->pending);
+
+       /* read current status of both alarms and the chip */
+       ds1307->reg_addr = DS1339_REG_ALARM1_SECS;
+       ds1307->msg[1].flags = I2C_M_RD;
+       ds1307->msg[1].len = 9;
+
+       ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
+                       ds1307->msg, 2);
+       if (ret != 2) {
+               dev_err(dev, "%s error %d\n", "alarm write", ret);
+               return -EIO;
+       }
+       control = ds1307->regs[7];
+       status = ds1307->regs[8];
+
+       dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
+                       "alarm set (old status)",
+                       ds1307->regs[0], ds1307->regs[1],
+                       ds1307->regs[2], ds1307->regs[3],
+                       ds1307->regs[4], ds1307->regs[5],
+                       ds1307->regs[6], control, status);
+
+       /* set ALARM1, using 24 hour and day-of-month modes */
+       *buf++ = DS1339_REG_ALARM1_SECS;        /* first register addr */
+       buf[0] = bin2bcd(t->time.tm_sec);
+       buf[1] = bin2bcd(t->time.tm_min);
+       buf[2] = bin2bcd(t->time.tm_hour);
+       buf[3] = bin2bcd(t->time.tm_mday);
+
+       /* set ALARM2 to non-garbage */
+       buf[4] = 0;
+       buf[5] = 0;
+       buf[6] = 0;
+
+       /* optionally enable ALARM1 */
+       buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
+       if (t->enabled) {
+               dev_dbg(dev, "alarm IRQ armed\n");
+               buf[7] |= DS1337_BIT_A1IE;      /* only ALARM1 is used */
+       }
+       buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
+
+       ds1307->msg[1].flags = 0;
+       ds1307->msg[1].len = 10;
+
+       ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
+                       &ds1307->msg[1], 1);
+       if (ret != 1) {
+               dev_err(dev, "can't set alarm time\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct ds1307           *ds1307 = i2c_get_clientdata(client);
+       int                     ret;
+
+       switch (cmd) {
+       case RTC_AIE_OFF:
+               if (!test_bit(HAS_ALARM, &ds1307->flags))
+                       return -ENOTTY;
+
+               ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+               if (ret < 0)
+                       return ret;
+
+               ret &= ~DS1337_BIT_A1IE;
+
+               ret = i2c_smbus_write_byte_data(client,
+                                               DS1337_REG_CONTROL, ret);
+               if (ret < 0)
+                       return ret;
+
+               break;
+
+       case RTC_AIE_ON:
+               if (!test_bit(HAS_ALARM, &ds1307->flags))
+                       return -ENOTTY;
+
+               ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+               if (ret < 0)
+                       return ret;
+
+               ret |= DS1337_BIT_A1IE;
+
+               ret = i2c_smbus_write_byte_data(client,
+                                               DS1337_REG_CONTROL, ret);
+               if (ret < 0)
+                       return ret;
+
+               break;
+
+       default:
+               return -ENOIOCTLCMD;
+       }
+
+       return 0;
+}
+
 static const struct rtc_class_ops ds13xx_rtc_ops = {
        .read_time      = ds1307_get_time,
        .set_time       = ds1307_set_time,
+       .read_alarm     = ds1307_read_alarm,
+       .set_alarm      = ds1307_set_alarm,
+       .ioctl          = ds1307_ioctl,
 };
 
 /*----------------------------------------------------------------------*/
@@ -327,6 +571,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
        int                     tmp;
        const struct chip_desc  *chip = &chips[id->driver_data];
        struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
+       int                     want_irq = false;
 
        if (!i2c_check_functionality(adapter,
                        I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
@@ -353,6 +598,12 @@ static int __devinit ds1307_probe(struct i2c_client *client,
        switch (ds1307->type) {
        case ds_1337:
        case ds_1339:
+               /* has IRQ? */
+               if (ds1307->client->irq > 0 && chip->alarm) {
+                       INIT_WORK(&ds1307->work, ds1307_work);
+                       want_irq = true;
+               }
+
                ds1307->reg_addr = DS1337_REG_CONTROL;
                ds1307->msg[1].len = 2;
 
@@ -369,8 +620,20 @@ static int __devinit ds1307_probe(struct i2c_client *client,
 
                /* oscillator off?  turn it on, so clock can tick. */
                if (ds1307->regs[0] & DS1337_BIT_nEOSC)
-                       i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
-                               ds1307->regs[0] & ~DS1337_BIT_nEOSC);
+                       ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
+
+               /* Using IRQ?  Disable the square wave and both alarms.
+                * For ds1339, be sure alarms can trigger when we're
+                * running on Vbackup (BBSQI); we assume ds1337 will
+                * ignore that bit
+                */
+               if (want_irq) {
+                       ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI;
+                       ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
+               }
+
+               i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
+                                                       ds1307->regs[0]);
 
                /* oscillator fault?  clear flag, and warn */
                if (ds1307->regs[1] & DS1337_BIT_OSF) {
@@ -495,10 +758,22 @@ read_rtc:
                goto exit_free;
        }
 
+       if (want_irq) {
+               err = request_irq(client->irq, ds1307_irq, 0,
+                         ds1307->rtc->name, client);
+               if (err) {
+                       dev_err(&client->dev,
+                               "unable to request IRQ!\n");
+                       goto exit_irq;
+               }
+               set_bit(HAS_ALARM, &ds1307->flags);
+               dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
+       }
+
        if (chip->nvram56) {
                err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
                if (err == 0) {
-                       ds1307->has_nvram = true;
+                       set_bit(HAS_NVRAM, &ds1307->flags);
                        dev_info(&client->dev, "56 bytes nvram\n");
                }
        }
@@ -512,7 +787,9 @@ exit_bad:
                        ds1307->regs[2], ds1307->regs[3],
                        ds1307->regs[4], ds1307->regs[5],
                        ds1307->regs[6]);
-
+exit_irq:
+       if (ds1307->rtc)
+               rtc_device_unregister(ds1307->rtc);
 exit_free:
        kfree(ds1307);
        return err;
@@ -520,9 +797,14 @@ exit_free:
 
 static int __devexit ds1307_remove(struct i2c_client *client)
 {
-       struct ds1307   *ds1307 = i2c_get_clientdata(client);
+       struct ds1307           *ds1307 = i2c_get_clientdata(client);
+
+       if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) {
+               free_irq(client->irq, client);
+               cancel_work_sync(&ds1307->work);
+       }
 
-       if (ds1307->has_nvram)
+       if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
                sysfs_remove_bin_file(&client->dev.kobj, &nvram);
 
        rtc_device_unregister(ds1307->rtc);
index a150418fba765d5db942db7bd2ffdb525716367e..a5b0fc09f0c673976720b10eca2cc3ecf8ff03bb 100644 (file)
@@ -429,12 +429,33 @@ static int __devexit ds1374_remove(struct i2c_client *client)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int ds1374_suspend(struct i2c_client *client, pm_message_t state)
+{
+       if (client->irq >= 0 && device_may_wakeup(&client->dev))
+               enable_irq_wake(client->irq);
+       return 0;
+}
+
+static int ds1374_resume(struct i2c_client *client)
+{
+       if (client->irq >= 0 && device_may_wakeup(&client->dev))
+               disable_irq_wake(client->irq);
+       return 0;
+}
+#else
+#define ds1374_suspend NULL
+#define ds1374_resume  NULL
+#endif
+
 static struct i2c_driver ds1374_driver = {
        .driver = {
                .name = "rtc-ds1374",
                .owner = THIS_MODULE,
        },
        .probe = ds1374_probe,
+       .suspend = ds1374_suspend,
+       .resume = ds1374_resume,
        .remove = __devexit_p(ds1374_remove),
        .id_table = ds1374_id,
 };
index 0f0d27d1c4ca366916b7958798ac44570681f679..86981d34fbb6717a66d47a11db1287b4e3a4c7f5 100644 (file)
@@ -379,18 +379,6 @@ ds1511_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
- static void
-ds1511_rtc_release(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
-       if (pdata->irq >= 0) {
-               pdata->irqen = 0;
-               ds1511_rtc_update_alarm(pdata);
-       }
-}
-
  static int
 ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
@@ -428,7 +416,6 @@ static const struct rtc_class_ops ds1511_rtc_ops = {
        .set_time       = ds1511_rtc_set_time,
        .read_alarm     = ds1511_rtc_read_alarm,
        .set_alarm      = ds1511_rtc_set_alarm,
-       .release        = ds1511_rtc_release,
        .ioctl          = ds1511_rtc_ioctl,
 };
 
index a19f1141554083058d5be71ac4064e81c97ac281..4ef59285b489ec28d05b9c038ae35d28e49a0b40 100644 (file)
@@ -207,17 +207,6 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void ds1553_rtc_release(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
-       if (pdata->irq >= 0) {
-               pdata->irqen = 0;
-               ds1553_rtc_update_alarm(pdata);
-       }
-}
-
 static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd,
                            unsigned long arg)
 {
@@ -254,7 +243,6 @@ static const struct rtc_class_ops ds1553_rtc_ops = {
        .set_time       = ds1553_rtc_set_time,
        .read_alarm     = ds1553_rtc_read_alarm,
        .set_alarm      = ds1553_rtc_set_alarm,
-       .release        = ds1553_rtc_release,
        .ioctl          = ds1553_rtc_ioctl,
 };
 
index 6fa4556f5f5c06b4d469e4a8c553d0d47357ebe0..341d7a5b45a28c3ecab9de39f9c0e515e5ac4331 100644 (file)
@@ -9,17 +9,10 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 
-#define DRV_VERSION "0.3"
-
-/* Addresses to scan: none. This chip cannot be detected. */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD;
+#define DRV_VERSION "0.4"
 
 /* Registers */
 
@@ -29,8 +22,7 @@ I2C_CLIENT_INSMOD;
 
 #define DS1672_REG_CONTROL_EOSC        0x80
 
-/* Prototypes */
-static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind);
+static struct i2c_driver ds1672_driver;
 
 /*
  * In the routines that deal directly with the ds1672 hardware, we use
@@ -44,8 +36,8 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
        unsigned char buf[4];
 
        struct i2c_msg msgs[] = {
-               { client->addr, 0, 1, &addr },          /* setup read ptr */
-               { client->addr, I2C_M_RD, 4, buf },     /* read date */
+               {client->addr, 0, 1, &addr},    /* setup read ptr */
+               {client->addr, I2C_M_RD, 4, buf},       /* read date */
        };
 
        /* read date registers */
@@ -80,7 +72,7 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
        buf[2] = (secs & 0x0000FF00) >> 8;
        buf[3] = (secs & 0x00FF0000) >> 16;
        buf[4] = (secs & 0xFF000000) >> 24;
-       buf[5] = 0;     /* set control reg to enable counting */
+       buf[5] = 0;             /* set control reg to enable counting */
 
        xfer = i2c_master_send(client, buf, 6);
        if (xfer != 6) {
@@ -127,8 +119,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
        unsigned char addr = DS1672_REG_CONTROL;
 
        struct i2c_msg msgs[] = {
-               { client->addr, 0, 1, &addr },          /* setup read ptr */
-               { client->addr, I2C_M_RD, 1, status },  /* read control */
+               {client->addr, 0, 1, &addr},    /* setup read ptr */
+               {client->addr, I2C_M_RD, 1, status},    /* read control */
        };
 
        /* read control register */
@@ -141,7 +133,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
 }
 
 /* following are the sysfs callback functions */
-static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_control(struct device *dev, struct device_attribute *attr,
+                           char *buf)
 {
        struct i2c_client *client = to_i2c_client(dev);
        u8 control;
@@ -152,85 +145,46 @@ static ssize_t show_control(struct device *dev, struct device_attribute *attr, c
                return err;
 
        return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC)
-                                       ? "disabled" : "enabled");
+                      ? "disabled" : "enabled");
 }
+
 static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
 
 static const struct rtc_class_ops ds1672_rtc_ops = {
-       .read_time      = ds1672_rtc_read_time,
-       .set_time       = ds1672_rtc_set_time,
-       .set_mmss       = ds1672_rtc_set_mmss,
+       .read_time = ds1672_rtc_read_time,
+       .set_time = ds1672_rtc_set_time,
+       .set_mmss = ds1672_rtc_set_mmss,
 };
 
-static int ds1672_attach(struct i2c_adapter *adapter)
+static int ds1672_remove(struct i2c_client *client)
 {
-       return i2c_probe(adapter, &addr_data, ds1672_probe);
-}
-
-static int ds1672_detach(struct i2c_client *client)
-{
-       int err;
        struct rtc_device *rtc = i2c_get_clientdata(client);
 
-       if (rtc)
+       if (rtc)
                rtc_device_unregister(rtc);
 
-       if ((err = i2c_detach_client(client)))
-               return err;
-
-       kfree(client);
-
        return 0;
 }
 
-static struct i2c_driver ds1672_driver = {
-       .driver         = {
-               .name   = "ds1672",
-       },
-       .id             = I2C_DRIVERID_DS1672,
-       .attach_adapter = &ds1672_attach,
-       .detach_client  = &ds1672_detach,
-};
-
-static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
+static int ds1672_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
 {
        int err = 0;
        u8 control;
-       struct i2c_client *client;
        struct rtc_device *rtc;
 
-       dev_dbg(&adapter->dev, "%s\n", __func__);
+       dev_dbg(&client->dev, "%s\n", __func__);
 
-       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-               err = -ENODEV;
-               goto exit;
-       }
-
-       if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
-               err = -ENOMEM;
-               goto exit;
-       }
-
-       /* I2C client */
-       client->addr = address;
-       client->driver = &ds1672_driver;
-       client->adapter = adapter;
-
-       strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE);
-
-       /* Inform the i2c layer */
-       if ((err = i2c_attach_client(client)))
-               goto exit_kfree;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+               return -ENODEV;
 
        dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
 
        rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
-                               &ds1672_rtc_ops, THIS_MODULE);
+                                 &ds1672_rtc_ops, THIS_MODULE);
 
-       if (IS_ERR(rtc)) {
-               err = PTR_ERR(rtc);
-               goto exit_detach;
-       }
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
 
        i2c_set_clientdata(client, rtc);
 
@@ -241,7 +195,7 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
 
        if (control & DS1672_REG_CONTROL_EOSC)
                dev_warn(&client->dev, "Oscillator not enabled. "
-                                       "Set time to enable.\n");
+                        "Set time to enable.\n");
 
        /* Register sysfs hooks */
        err = device_create_file(&client->dev, &dev_attr_control);
@@ -250,19 +204,19 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
 
        return 0;
 
-exit_devreg:
+ exit_devreg:
        rtc_device_unregister(rtc);
-
-exit_detach:
-       i2c_detach_client(client);
-
-exit_kfree:
-       kfree(client);
-
-exit:
        return err;
 }
 
+static struct i2c_driver ds1672_driver = {
+       .driver = {
+                  .name = "rtc-ds1672",
+                  },
+       .probe = &ds1672_probe,
+       .remove = &ds1672_remove,
+};
+
 static int __init ds1672_init(void)
 {
        return i2c_add_driver(&ds1672_driver);
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
new file mode 100644 (file)
index 0000000..37d131d
--- /dev/null
@@ -0,0 +1,290 @@
+/* drivers/rtc/rtc-ds3234.c
+ *
+ * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal
+ * and SRAM.
+ *
+ * Copyright (C) 2008 MIMOMax Wireless Ltd.
+ *
+ * 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.
+ *
+ * Changelog:
+ *
+ * 07-May-2008: Dennis Aberilla <denzzzhome@yahoo.com>
+ *             - Created based on the max6902 code. Only implements the
+ *               date/time keeping functions; no SRAM yet.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/spi/spi.h>
+#include <linux/bcd.h>
+
+#define DS3234_REG_SECONDS     0x00
+#define DS3234_REG_MINUTES     0x01
+#define DS3234_REG_HOURS       0x02
+#define DS3234_REG_DAY         0x03
+#define DS3234_REG_DATE                0x04
+#define DS3234_REG_MONTH       0x05
+#define DS3234_REG_YEAR                0x06
+#define DS3234_REG_CENTURY     (1 << 7) /* Bit 7 of the Month register */
+
+#define DS3234_REG_CONTROL     0x0E
+#define DS3234_REG_CONT_STAT   0x0F
+
+#undef DS3234_DEBUG
+
+struct ds3234 {
+       struct rtc_device *rtc;
+       u8 buf[8]; /* Burst read: addr + 7 regs */
+       u8 tx_buf[2];
+       u8 rx_buf[2];
+};
+
+static void ds3234_set_reg(struct device *dev, unsigned char address,
+                               unsigned char data)
+{
+       struct spi_device *spi = to_spi_device(dev);
+       unsigned char buf[2];
+
+       /* MSB must be '1' to indicate write */
+       buf[0] = address | 0x80;
+       buf[1] = data;
+
+       spi_write(spi, buf, 2);
+}
+
+static int ds3234_get_reg(struct device *dev, unsigned char address,
+                               unsigned char *data)
+{
+       struct spi_device *spi = to_spi_device(dev);
+       struct ds3234 *chip = dev_get_drvdata(dev);
+       struct spi_message message;
+       struct spi_transfer xfer;
+       int status;
+
+       if (!data)
+               return -EINVAL;
+
+       /* Build our spi message */
+       spi_message_init(&message);
+       memset(&xfer, 0, sizeof(xfer));
+
+       /* Address + dummy tx byte */
+       xfer.len = 2;
+       xfer.tx_buf = chip->tx_buf;
+       xfer.rx_buf = chip->rx_buf;
+
+       chip->tx_buf[0] = address;
+       chip->tx_buf[1] = 0xff;
+
+       spi_message_add_tail(&xfer, &message);
+
+       /* do the i/o */
+       status = spi_sync(spi, &message);
+       if (status == 0)
+               status = message.status;
+       else
+               return status;
+
+       *data = chip->rx_buf[1];
+
+       return status;
+}
+
+static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt)
+{
+       struct spi_device *spi = to_spi_device(dev);
+       struct ds3234 *chip = dev_get_drvdata(dev);
+       struct spi_message message;
+       struct spi_transfer xfer;
+       int status;
+
+       /* build the message */
+       spi_message_init(&message);
+       memset(&xfer, 0, sizeof(xfer));
+       xfer.len = 1 + 7;       /* Addr + 7 registers */
+       xfer.tx_buf = chip->buf;
+       xfer.rx_buf = chip->buf;
+       chip->buf[0] = 0x00;    /* Start address */
+       spi_message_add_tail(&xfer, &message);
+
+       /* do the i/o */
+       status = spi_sync(spi, &message);
+       if (status == 0)
+               status = message.status;
+       else
+               return status;
+
+       /* Seconds, Minutes, Hours, Day, Date, Month, Year */
+       dt->tm_sec      = bcd2bin(chip->buf[1]);
+       dt->tm_min      = bcd2bin(chip->buf[2]);
+       dt->tm_hour     = bcd2bin(chip->buf[3] & 0x3f);
+       dt->tm_wday     = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */
+       dt->tm_mday     = bcd2bin(chip->buf[5]);
+       dt->tm_mon      = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */
+       dt->tm_year     = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */
+
+#ifdef DS3234_DEBUG
+       dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
+       dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+       dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+       dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+       dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+       dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+       dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+       dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+#endif
+
+       return 0;
+}
+
+static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt)
+{
+#ifdef DS3234_DEBUG
+       dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
+       dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+       dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+       dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+       dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+       dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+       dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+       dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+#endif
+
+       ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec));
+       ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min));
+       ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f);
+
+       /* 0 = Sun */
+       ds3234_set_reg(dev, DS3234_REG_DAY, bin2bcd(dt->tm_wday + 1));
+       ds3234_set_reg(dev, DS3234_REG_DATE, bin2bcd(dt->tm_mday));
+
+       /* 0 = Jan */
+       ds3234_set_reg(dev, DS3234_REG_MONTH, bin2bcd(dt->tm_mon + 1));
+
+       /* Assume 20YY although we just want to make sure not to go negative. */
+       if (dt->tm_year > 100)
+               dt->tm_year -= 100;
+
+       ds3234_set_reg(dev, DS3234_REG_YEAR, bin2bcd(dt->tm_year));
+
+       return 0;
+}
+
+static int ds3234_read_time(struct device *dev, struct rtc_time *tm)
+{
+       return ds3234_get_datetime(dev, tm);
+}
+
+static int ds3234_set_time(struct device *dev, struct rtc_time *tm)
+{
+       return ds3234_set_datetime(dev, tm);
+}
+
+static const struct rtc_class_ops ds3234_rtc_ops = {
+       .read_time      = ds3234_read_time,
+       .set_time       = ds3234_set_time,
+};
+
+static int ds3234_probe(struct spi_device *spi)
+{
+       struct rtc_device *rtc;
+       unsigned char tmp;
+       struct ds3234 *chip;
+       int res;
+
+       rtc = rtc_device_register("ds3234",
+                               &spi->dev, &ds3234_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
+
+       spi->mode = SPI_MODE_3;
+       spi->bits_per_word = 8;
+       spi_setup(spi);
+
+       chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL);
+       if (!chip) {
+               rtc_device_unregister(rtc);
+               return -ENOMEM;
+       }
+       chip->rtc = rtc;
+       dev_set_drvdata(&spi->dev, chip);
+
+       res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp);
+       if (res) {
+               rtc_device_unregister(rtc);
+               return res;
+       }
+
+       /* Control settings
+        *
+        * CONTROL_REG
+        * BIT 7        6       5       4       3       2       1       0
+        *     EOSC     BBSQW   CONV    RS2     RS1     INTCN   A2IE    A1IE
+        *
+        *     0        0       0       1       1       1       0       0
+        *
+        * CONTROL_STAT_REG
+        * BIT 7        6       5       4       3       2       1       0
+        *     OSF      BB32kHz CRATE1  CRATE0  EN32kHz BSY     A2F     A1F
+        *
+        *     1        0       0       0       1       0       0       0
+        */
+       ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
+       ds3234_set_reg(&spi->dev, DS3234_REG_CONTROL, tmp & 0x1c);
+
+       ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
+       ds3234_set_reg(&spi->dev, DS3234_REG_CONT_STAT, tmp & 0x88);
+
+       /* Print our settings */
+       ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
+       dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
+
+       ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
+       dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
+
+       return 0;
+}
+
+static int __exit ds3234_remove(struct spi_device *spi)
+{
+       struct ds3234 *chip = platform_get_drvdata(spi);
+       struct rtc_device *rtc = chip->rtc;
+
+       if (rtc)
+               rtc_device_unregister(rtc);
+
+       kfree(chip);
+
+       return 0;
+}
+
+static struct spi_driver ds3234_driver = {
+       .driver = {
+               .name    = "ds3234",
+               .bus    = &spi_bus_type,
+               .owner  = THIS_MODULE,
+       },
+       .probe   = ds3234_probe,
+       .remove = __devexit_p(ds3234_remove),
+};
+
+static __init int ds3234_init(void)
+{
+       printk(KERN_INFO "DS3234 SPI RTC Driver\n");
+       return spi_register_driver(&ds3234_driver);
+}
+module_init(ds3234_init);
+
+static __exit void ds3234_exit(void)
+{
+       spi_unregister_driver(&ds3234_driver);
+}
+module_exit(ds3234_exit);
+
+MODULE_DESCRIPTION("DS3234 SPI RTC driver");
+MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
+MODULE_LICENSE("GPL");
index 24bc1689fc74c095d88641cb7c78755e5ee0b9f8..470fb2d295452a7be54f92747076107c0c025436 100644 (file)
 #define M41T80_ALHOUR_HT       (1 << 6)        /* HT: Halt Update Bit */
 #define M41T80_FLAGS_AF                (1 << 6)        /* AF: Alarm Flag Bit */
 #define M41T80_FLAGS_BATT_LOW  (1 << 4)        /* BL: Battery Low Bit */
+#define M41T80_WATCHDOG_RB2    (1 << 7)        /* RB: Watchdog resolution */
+#define M41T80_WATCHDOG_RB1    (1 << 1)        /* RB: Watchdog resolution */
+#define M41T80_WATCHDOG_RB0    (1 << 0)        /* RB: Watchdog resolution */
 
-#define M41T80_FEATURE_HT      (1 << 0)
-#define M41T80_FEATURE_BL      (1 << 1)
+#define M41T80_FEATURE_HT      (1 << 0)        /* Halt feature */
+#define M41T80_FEATURE_BL      (1 << 1)        /* Battery low indicator */
+#define M41T80_FEATURE_SQ      (1 << 2)        /* Squarewave feature */
+#define M41T80_FEATURE_WD      (1 << 3)        /* Extra watchdog resolution */
 
 #define DRV_VERSION "0.05"
 
 static const struct i2c_device_id m41t80_id[] = {
-       { "m41t80", 0 },
-       { "m41t81", M41T80_FEATURE_HT },
-       { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
-       { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
-       { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
-       { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
-       { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
-       { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+       { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
+       { "m41t80", M41T80_FEATURE_SQ },
+       { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
+       { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+       { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+       { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+       { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+       { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+       { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, m41t80_id);
@@ -386,8 +392,12 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct i2c_client *client = to_i2c_client(dev);
+       struct m41t80_data *clientdata = i2c_get_clientdata(client);
        int val;
 
+       if (!(clientdata->features & M41T80_FEATURE_SQ))
+               return -EINVAL;
+
        val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
        if (val < 0)
                return -EIO;
@@ -408,9 +418,13 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
                                const char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
+       struct m41t80_data *clientdata = i2c_get_clientdata(client);
        int almon, sqw;
        int val = simple_strtoul(buf, NULL, 0);
 
+       if (!(clientdata->features & M41T80_FEATURE_SQ))
+               return -EINVAL;
+
        if (val) {
                if (!is_power_of_2(val))
                        return -EINVAL;
@@ -499,6 +513,8 @@ static void wdt_ping(void)
                        .buf    = i2c_data,
                },
        };
+       struct m41t80_data *clientdata = i2c_get_clientdata(save_client);
+
        i2c_data[0] = 0x09;             /* watchdog register */
 
        if (wdt_margin > 31)
@@ -509,6 +525,13 @@ static void wdt_ping(void)
                 */
                i2c_data[1] = wdt_margin<<2 | 0x82;
 
+       /*
+        * M41T65 has three bits for watchdog resolution.  Don't set bit 7, as
+        * that would be an invalid resolution.
+        */
+       if (clientdata->features & M41T80_FEATURE_WD)
+               i2c_data[1] &= ~M41T80_WATCHDOG_RB2;
+
        i2c_transfer(save_client->adapter, msgs1, 1);
 }
 
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
new file mode 100644 (file)
index 0000000..0b21975
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ *
+ * Copyright (C) 2008 Thomas Bogendoerfer
+ *
+ * Based on code written by Paul Gortmaker.
+ *
+ * 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/module.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/bcd.h>
+#include <linux/io.h>
+
+#define DRV_VERSION            "1.0"
+
+struct m48t35_rtc {
+       u8      pad[0x7ff8];    /* starts at 0x7ff8 */
+       u8      control;
+       u8      sec;
+       u8      min;
+       u8      hour;
+       u8      day;
+       u8      date;
+       u8      month;
+       u8      year;
+};
+
+#define M48T35_RTC_SET         0x80
+#define M48T35_RTC_READ                0x40
+
+struct m48t35_priv {
+       struct rtc_device *rtc;
+       struct m48t35_rtc __iomem *reg;
+       size_t size;
+       unsigned long baseaddr;
+       spinlock_t lock;
+};
+
+static int m48t35_read_time(struct device *dev, struct rtc_time *tm)
+{
+       struct m48t35_priv *priv = dev_get_drvdata(dev);
+       u8 control;
+
+       /*
+        * Only the values that we read from the RTC are set. We leave
+        * tm_wday, tm_yday and tm_isdst untouched. Even though the
+        * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
+        * by the RTC when initially set to a non-zero value.
+        */
+       spin_lock_irq(&priv->lock);
+       control = readb(&priv->reg->control);
+       writeb(control | M48T35_RTC_READ, &priv->reg->control);
+       tm->tm_sec = readb(&priv->reg->sec);
+       tm->tm_min = readb(&priv->reg->min);
+       tm->tm_hour = readb(&priv->reg->hour);
+       tm->tm_mday = readb(&priv->reg->date);
+       tm->tm_mon = readb(&priv->reg->month);
+       tm->tm_year = readb(&priv->reg->year);
+       writeb(control, &priv->reg->control);
+       spin_unlock_irq(&priv->lock);
+
+       tm->tm_sec = bcd2bin(tm->tm_sec);
+       tm->tm_min = bcd2bin(tm->tm_min);
+       tm->tm_hour = bcd2bin(tm->tm_hour);
+       tm->tm_mday = bcd2bin(tm->tm_mday);
+       tm->tm_mon = bcd2bin(tm->tm_mon);
+       tm->tm_year = bcd2bin(tm->tm_year);
+
+       /*
+        * Account for differences between how the RTC uses the values
+        * and how they are defined in a struct rtc_time;
+        */
+       tm->tm_year += 70;
+       if (tm->tm_year <= 69)
+               tm->tm_year += 100;
+
+       tm->tm_mon--;
+       return rtc_valid_tm(tm);
+}
+
+static int m48t35_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct m48t35_priv *priv = dev_get_drvdata(dev);
+       unsigned char mon, day, hrs, min, sec;
+       unsigned int yrs;
+       u8 control;
+
+       yrs = tm->tm_year + 1900;
+       mon = tm->tm_mon + 1;   /* tm_mon starts at zero */
+       day = tm->tm_mday;
+       hrs = tm->tm_hour;
+       min = tm->tm_min;
+       sec = tm->tm_sec;
+
+       if (yrs < 1970)
+               return -EINVAL;
+
+       yrs -= 1970;
+       if (yrs > 255)    /* They are unsigned */
+               return -EINVAL;
+
+       if (yrs > 169)
+               return -EINVAL;
+
+       if (yrs >= 100)
+               yrs -= 100;
+
+       sec = bin2bcd(sec);
+       min = bin2bcd(min);
+       hrs = bin2bcd(hrs);
+       day = bin2bcd(day);
+       mon = bin2bcd(mon);
+       yrs = bin2bcd(yrs);
+
+       spin_lock_irq(&priv->lock);
+       control = readb(&priv->reg->control);
+       writeb(control | M48T35_RTC_SET, &priv->reg->control);
+       writeb(yrs, &priv->reg->year);
+       writeb(mon, &priv->reg->month);
+       writeb(day, &priv->reg->date);
+       writeb(hrs, &priv->reg->hour);
+       writeb(min, &priv->reg->min);
+       writeb(sec, &priv->reg->sec);
+       writeb(control, &priv->reg->control);
+       spin_unlock_irq(&priv->lock);
+       return 0;
+}
+
+static const struct rtc_class_ops m48t35_ops = {
+       .read_time      = m48t35_read_time,
+       .set_time       = m48t35_set_time,
+};
+
+static int __devinit m48t35_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtc;
+       struct resource *res;
+       struct m48t35_priv *priv;
+       int ret = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+       priv = kzalloc(sizeof(struct m48t35_priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->size = res->end - res->start + 1;
+       /*
+        * kludge: remove the #ifndef after ioc3 resource
+        * conflicts are resolved
+        */
+#ifndef CONFIG_SGI_IP27
+       if (!request_mem_region(res->start, priv->size, pdev->name)) {
+               ret = -EBUSY;
+               goto out;
+       }
+#endif
+       priv->baseaddr = res->start;
+       priv->reg = ioremap(priv->baseaddr, priv->size);
+       if (!priv->reg) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       spin_lock_init(&priv->lock);
+       rtc = rtc_device_register("m48t35", &pdev->dev,
+                                 &m48t35_ops, THIS_MODULE);
+       if (IS_ERR(rtc)) {
+               ret = PTR_ERR(rtc);
+               goto out;
+       }
+       priv->rtc = rtc;
+       platform_set_drvdata(pdev, priv);
+       return 0;
+
+out:
+       if (priv->rtc)
+               rtc_device_unregister(priv->rtc);
+       if (priv->reg)
+               iounmap(priv->reg);
+       if (priv->baseaddr)
+               release_mem_region(priv->baseaddr, priv->size);
+       kfree(priv);
+       return ret;
+}
+
+static int __devexit m48t35_remove(struct platform_device *pdev)
+{
+       struct m48t35_priv *priv = platform_get_drvdata(pdev);
+
+       rtc_device_unregister(priv->rtc);
+       iounmap(priv->reg);
+#ifndef CONFIG_SGI_IP27
+       release_mem_region(priv->baseaddr, priv->size);
+#endif
+       kfree(priv);
+       return 0;
+}
+
+static struct platform_driver m48t35_platform_driver = {
+       .driver         = {
+               .name   = "rtc-m48t35",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = m48t35_probe,
+       .remove         = __devexit_p(m48t35_remove),
+};
+
+static int __init m48t35_init(void)
+{
+       return platform_driver_register(&m48t35_platform_driver);
+}
+
+static void __exit m48t35_exit(void)
+{
+       platform_driver_unregister(&m48t35_platform_driver);
+}
+
+MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
+MODULE_DESCRIPTION("M48T35 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:rtc-m48t35");
+
+module_init(m48t35_init);
+module_exit(m48t35_exit);
index ded3c0abad835736152c093d9ae5dc0402afec58..12c9cd25cad8b2b3df1843ba74d247f592334e41 100644 (file)
 #include <linux/rtc.h>
 #include <linux/delay.h>
 
-#define DRV_NAME "max6900"
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
 
 /*
  * register indices
  */
-#define MAX6900_REG_SC                 0       /* seconds      00-59 */
-#define MAX6900_REG_MN                 1       /* minutes      00-59 */
-#define MAX6900_REG_HR                 2       /* hours        00-23 */
-#define MAX6900_REG_DT                 3       /* day of month 00-31 */
-#define MAX6900_REG_MO                 4       /* month        01-12 */
-#define MAX6900_REG_DW                 5       /* day of week   1-7  */
-#define MAX6900_REG_YR                 6       /* year         00-99 */
+#define MAX6900_REG_SC                 0       /* seconds      00-59 */
+#define MAX6900_REG_MN                 1       /* minutes      00-59 */
+#define MAX6900_REG_HR                 2       /* hours        00-23 */
+#define MAX6900_REG_DT                 3       /* day of month 00-31 */
+#define MAX6900_REG_MO                 4       /* month        01-12 */
+#define MAX6900_REG_DW                 5       /* day of week   1-7  */
+#define MAX6900_REG_YR                 6       /* year         00-99 */
 #define MAX6900_REG_CT                 7       /* control */
                                                /* register 8 is undocumented */
 #define MAX6900_REG_CENTURY            9       /* century */
@@ -39,7 +38,6 @@
 
 #define MAX6900_REG_CT_WP              (1 << 7)        /* Write Protect */
 
-
 /*
  * register read/write commands
  */
 
 #define MAX6900_IDLE_TIME_AFTER_WRITE  3       /* specification says 2.5 mS */
 
-#define MAX6900_I2C_ADDR               0xa0
-
-static const unsigned short normal_i2c[] = {
-       MAX6900_I2C_ADDR >> 1,
-       I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;                     /* defines addr_data */
-
-static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
+static struct i2c_driver max6900_driver;
 
 static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
 {
@@ -69,36 +58,35 @@ static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
        u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ };
        struct i2c_msg msgs[4] = {
                {
-                       .addr   = client->addr,
-                       .flags  = 0, /* write */
-                       .len    = sizeof(reg_burst_read),
-                       .buf    = reg_burst_read
-               },
+                .addr = client->addr,
+                .flags = 0,    /* write */
+                .len = sizeof(reg_burst_read),
+                .buf = reg_burst_read}
+               ,
                {
-                       .addr   = client->addr,
-                       .flags  = I2C_M_RD,
-                       .len    = MAX6900_BURST_LEN,
-                       .buf    = buf
-               },
+                .addr = client->addr,
+                .flags = I2C_M_RD,
+                .len = MAX6900_BURST_LEN,
+                .buf = buf}
+               ,
                {
-                       .addr   = client->addr,
-                       .flags  = 0, /* write */
-                       .len    = sizeof(reg_century_read),
-                       .buf    = reg_century_read
-               },
+                .addr = client->addr,
+                .flags = 0,    /* write */
+                .len = sizeof(reg_century_read),
+                .buf = reg_century_read}
+               ,
                {
-                       .addr   = client->addr,
-                       .flags  = I2C_M_RD,
-                       .len    = sizeof(buf[MAX6900_REG_CENTURY]),
-                       .buf    = &buf[MAX6900_REG_CENTURY]
-               }
+                .addr = client->addr,
+                .flags = I2C_M_RD,
+                .len = sizeof(buf[MAX6900_REG_CENTURY]),
+                .buf = &buf[MAX6900_REG_CENTURY]
+                }
        };
        int rc;
 
        rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
        if (rc != ARRAY_SIZE(msgs)) {
-               dev_err(&client->dev, "%s: register read failed\n",
-                       __func__);
+               dev_err(&client->dev, "%s: register read failed\n", __func__);
                return -EIO;
        }
        return 0;
@@ -109,20 +97,18 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
        u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE };
        struct i2c_msg century_msgs[1] = {
                {
-                       .addr   = client->addr,
-                       .flags  = 0, /* write */
-                       .len    = sizeof(i2c_century_buf),
-                       .buf    = i2c_century_buf
-               }
+                .addr = client->addr,
+                .flags = 0,    /* write */
+                .len = sizeof(i2c_century_buf),
+                .buf = i2c_century_buf}
        };
        u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE };
        struct i2c_msg burst_msgs[1] = {
                {
-                       .addr   = client->addr,
-                       .flags  = 0, /* write */
-                       .len    = sizeof(i2c_burst_buf),
-                       .buf    = i2c_burst_buf
-               }
+                .addr = client->addr,
+                .flags = 0,    /* write */
+                .len = sizeof(i2c_burst_buf),
+                .buf = i2c_burst_buf}
        };
        int rc;
 
@@ -133,10 +119,12 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
         * bit as part of the burst write.
         */
        i2c_century_buf[1] = buf[MAX6900_REG_CENTURY];
+
        rc = i2c_transfer(client->adapter, century_msgs,
                          ARRAY_SIZE(century_msgs));
        if (rc != ARRAY_SIZE(century_msgs))
                goto write_failed;
+
        msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
 
        memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN);
@@ -148,45 +136,11 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
 
        return 0;
 
-write_failed:
-       dev_err(&client->dev, "%s: register write failed\n",
-               __func__);
+ write_failed:
+       dev_err(&client->dev, "%s: register write failed\n", __func__);
        return -EIO;
 }
 
-static int max6900_i2c_validate_client(struct i2c_client *client)
-{
-       u8 regs[MAX6900_REG_LEN];
-       u8 zero_mask[] = {
-               0x80,   /* seconds */
-               0x80,   /* minutes */
-               0x40,   /* hours */
-               0xc0,   /* day of month */
-               0xe0,   /* month */
-               0xf8,   /* day of week */
-               0x00,   /* year */
-               0x7f,   /* control */
-       };
-       int i;
-       int rc;
-       int reserved;
-
-       reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
-       if (reserved != 0x07)
-               return -ENODEV;
-
-       rc = max6900_i2c_read_regs(client, regs);
-       if (rc < 0)
-               return rc;
-
-       for (i = 0; i < ARRAY_SIZE(zero_mask); ++i) {
-               if (regs[i] & zero_mask[i])
-                       return -ENODEV;
-       }
-
-       return 0;
-}
-
 static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
        int rc;
@@ -202,7 +156,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
        tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
        tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
        tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) +
-                     BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
+           BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
        tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
 
        return 0;
@@ -211,7 +165,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 static int max6900_i2c_clear_write_protect(struct i2c_client *client)
 {
        int rc;
-       rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0);
+       rc = i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0);
        if (rc < 0) {
                dev_err(&client->dev, "%s: control register write failed\n",
                        __func__);
@@ -220,8 +174,8 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client)
        return 0;
 }
 
-static int max6900_i2c_set_time(struct i2c_client *client,
-                               struct rtc_time const *tm)
+static int
+max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 {
        u8 regs[MAX6900_REG_LEN];
        int rc;
@@ -258,89 +212,49 @@ static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
        return max6900_i2c_set_time(to_i2c_client(dev), tm);
 }
 
-static int max6900_attach_adapter(struct i2c_adapter *adapter)
-{
-       return i2c_probe(adapter, &addr_data, max6900_probe);
-}
-
-static int max6900_detach_client(struct i2c_client *client)
+static int max6900_remove(struct i2c_client *client)
 {
-       struct rtc_device *const rtc = i2c_get_clientdata(client);
+       struct rtc_device *rtc = i2c_get_clientdata(client);
 
        if (rtc)
                rtc_device_unregister(rtc);
 
-       return i2c_detach_client(client);
+       return 0;
 }
 
-static struct i2c_driver max6900_driver = {
-       .driver         = {
-               .name   = DRV_NAME,
-       },
-       .id             = I2C_DRIVERID_MAX6900,
-       .attach_adapter = max6900_attach_adapter,
-       .detach_client  = max6900_detach_client,
-};
-
 static const struct rtc_class_ops max6900_rtc_ops = {
-       .read_time      = max6900_rtc_read_time,
-       .set_time       = max6900_rtc_set_time,
+       .read_time = max6900_rtc_read_time,
+       .set_time = max6900_rtc_set_time,
 };
 
-static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int
+max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-       int rc = 0;
-       struct i2c_client *client = NULL;
-       struct rtc_device *rtc = NULL;
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-               rc = -ENODEV;
-               goto failout;
-       }
-
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == NULL) {
-               rc = -ENOMEM;
-               goto failout;
-       }
-
-       client->addr = addr;
-       client->adapter = adapter;
-       client->driver = &max6900_driver;
-       strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
-
-       if (kind < 0) {
-               rc = max6900_i2c_validate_client(client);
-               if (rc < 0)
-                       goto failout;
-       }
+       struct rtc_device *rtc;
 
-       rc = i2c_attach_client(client);
-       if (rc < 0)
-               goto failout;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+               return -ENODEV;
 
-       dev_info(&client->dev,
-                "chip found, driver version " DRV_VERSION "\n");
+       dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
 
        rtc = rtc_device_register(max6900_driver.driver.name,
-                                 &client->dev,
-                                 &max6900_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               rc = PTR_ERR(rtc);
-               goto failout_detach;
-       }
+                                 &client->dev, &max6900_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc))
+               return PTR_ERR(rtc);
 
        i2c_set_clientdata(client, rtc);
 
        return 0;
-
-failout_detach:
-       i2c_detach_client(client);
-failout:
-       kfree(client);
-       return rc;
 }
 
+static struct i2c_driver max6900_driver = {
+       .driver = {
+                  .name = "rtc-max6900",
+                  },
+       .probe = max6900_probe,
+       .remove = max6900_remove,
+};
+
 static int __init max6900_init(void)
 {
        return i2c_add_driver(&max6900_driver);
@@ -352,6 +266,7 @@ static void __exit max6900_exit(void)
 }
 
 MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
+MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
index 748a502a63558fd499e26d56338132aabcae85f2..a829f20ad6d6eb140d56d246ab620af0640507d7 100644 (file)
@@ -179,58 +179,6 @@ struct pcf8563_limit
        unsigned char max;
 };
 
-static int pcf8563_validate_client(struct i2c_client *client)
-{
-       int i;
-
-       static const struct pcf8563_limit pattern[] = {
-               /* register, mask, min, max */
-               { PCF8563_REG_SC,       0x7F,   0,      59      },
-               { PCF8563_REG_MN,       0x7F,   0,      59      },
-               { PCF8563_REG_HR,       0x3F,   0,      23      },
-               { PCF8563_REG_DM,       0x3F,   0,      31      },
-               { PCF8563_REG_MO,       0x1F,   0,      12      },
-       };
-
-       /* check limits (only registers with bcd values) */
-       for (i = 0; i < ARRAY_SIZE(pattern); i++) {
-               int xfer;
-               unsigned char value;
-               unsigned char buf = pattern[i].reg;
-
-               struct i2c_msg msgs[] = {
-                       { client->addr, 0, 1, &buf },
-                       { client->addr, I2C_M_RD, 1, &buf },
-               };
-
-               xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-
-               if (xfer != ARRAY_SIZE(msgs)) {
-                       dev_err(&client->dev,
-                               "%s: could not read register 0x%02X\n",
-                               __func__, pattern[i].reg);
-
-                       return -EIO;
-               }
-
-               value = BCD2BIN(buf & pattern[i].mask);
-
-               if (value > pattern[i].max ||
-                       value < pattern[i].min) {
-                       dev_dbg(&client->dev,
-                               "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, "
-                               "max=%d, value=%d, raw=0x%02X\n",
-                               __func__, i, pattern[i].reg, pattern[i].mask,
-                               pattern[i].min, pattern[i].max,
-                               value, buf);
-
-                       return -ENODEV;
-               }
-       }
-
-       return 0;
-}
-
 static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        return pcf8563_get_datetime(to_i2c_client(dev), tm);
@@ -262,12 +210,6 @@ static int pcf8563_probe(struct i2c_client *client,
        if (!pcf8563)
                return -ENOMEM;
 
-       /* Verify the chip is really an PCF8563 */
-       if (pcf8563_validate_client(client) < 0) {
-               err = -ENODEV;
-               goto exit_kfree;
-       }
-
        dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
 
        pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,
index 8448eeb9d675f8ca37c79e506ba63143ea7bf1a2..826153552157d3d4d328fe372fa2dd2fbf025ac6 100644 (file)
@@ -34,15 +34,6 @@ static irqreturn_t pl030_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int pl030_open(struct device *dev)
-{
-       return 0;
-}
-
-static void pl030_release(struct device *dev)
-{
-}
-
 static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
        return -ENOIOCTLCMD;
@@ -104,8 +95,6 @@ static int pl030_set_time(struct device *dev, struct rtc_time *tm)
 }
 
 static const struct rtc_class_ops pl030_ops = {
-       .open           = pl030_open,
-       .release        = pl030_release,
        .ioctl          = pl030_ioctl,
        .read_time      = pl030_read_time,
        .set_time       = pl030_set_time,
index 08b4610ec5a6ca218567f25c552516effa33b6fa..333eec689d2feae84723d8622b972d936552c55f 100644 (file)
@@ -45,18 +45,6 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int pl031_open(struct device *dev)
-{
-       /*
-        * We request IRQ in pl031_probe, so nothing to do here...
-        */
-       return 0;
-}
-
-static void pl031_release(struct device *dev)
-{
-}
-
 static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
        struct pl031_local *ldata = dev_get_drvdata(dev);
@@ -118,8 +106,6 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 }
 
 static const struct rtc_class_ops pl031_ops = {
-       .open = pl031_open,
-       .release = pl031_release,
        .ioctl = pl031_ioctl,
        .read_time = pl031_read_time,
        .set_time = pl031_set_time,
index 56caf6b2c3e5d2fceface127d7dc197a839e0dac..8b561958fb1e62056c62ef2aabe37742ab2cd395 100644 (file)
@@ -1,8 +1,9 @@
 /*
- * An I2C driver for Ricoh RS5C372 and RV5C38[67] RTCs
+ * An I2C driver for Ricoh RS5C372, R2025S/D and RV5C38[67] RTCs
  *
  * Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net>
  * Copyright (C) 2006 Tower Technologies
+ * Copyright (C) 2008 Paul Mundt
  *
  * 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
@@ -13,7 +14,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 
-#define DRV_VERSION "0.5"
+#define DRV_VERSION "0.6"
 
 
 /*
@@ -51,7 +52,8 @@
 #      define RS5C_CTRL1_CT4           (4 << 0)        /* 1 Hz level irq */
 #define RS5C_REG_CTRL2         15
 #      define RS5C372_CTRL2_24         (1 << 5)
-#      define RS5C_CTRL2_XSTP          (1 << 4)
+#      define R2025_CTRL2_XST          (1 << 5)
+#      define RS5C_CTRL2_XSTP          (1 << 4)        /* only if !R2025S/D */
 #      define RS5C_CTRL2_CTFG          (1 << 2)
 #      define RS5C_CTRL2_AAFG          (1 << 1)        /* or WAFG */
 #      define RS5C_CTRL2_BAFG          (1 << 0)        /* or DAFG */
@@ -63,6 +65,7 @@
 
 enum rtc_type {
        rtc_undef = 0,
+       rtc_r2025sd,
        rtc_rs5c372a,
        rtc_rs5c372b,
        rtc_rv5c386,
@@ -70,6 +73,7 @@ enum rtc_type {
 };
 
 static const struct i2c_device_id rs5c372_id[] = {
+       { "r2025sd", rtc_r2025sd },
        { "rs5c372a", rtc_rs5c372a },
        { "rs5c372b", rtc_rs5c372b },
        { "rv5c386", rtc_rv5c386 },
@@ -89,6 +93,7 @@ struct rs5c372 {
        enum rtc_type           type;
        unsigned                time24:1;
        unsigned                has_irq:1;
+       unsigned                smbus:1;
        char                    buf[17];
        char                    *regs;
 };
@@ -106,10 +111,25 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
         *
         * The first method doesn't work with the iop3xx adapter driver, on at
         * least 80219 chips; this works around that bug.
+        *
+        * The third method on the other hand doesn't work for the SMBus-only
+        * configurations, so we use the the first method there, stripping off
+        * the extra register in the process.
         */
-       if ((i2c_transfer(client->adapter, msgs, 1)) != 1) {
-               dev_warn(&client->dev, "can't read registers\n");
-               return -EIO;
+       if (rs5c->smbus) {
+               int addr = RS5C_ADDR(RS5C372_REG_SECS);
+               int size = sizeof(rs5c->buf) - 1;
+
+               if (i2c_smbus_read_i2c_block_data(client, addr, size,
+                                                 rs5c->buf + 1) != size) {
+                       dev_warn(&client->dev, "can't read registers\n");
+                       return -EIO;
+               }
+       } else {
+               if ((i2c_transfer(client->adapter, msgs, 1)) != 1) {
+                       dev_warn(&client->dev, "can't read registers\n");
+                       return -EIO;
+               }
        }
 
        dev_dbg(&client->dev,
@@ -187,6 +207,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
        struct rs5c372  *rs5c = i2c_get_clientdata(client);
        unsigned char   buf[8];
+       int             addr;
 
        dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
                "mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -194,16 +215,16 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
                tm->tm_sec, tm->tm_min, tm->tm_hour,
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 
-       buf[0] = RS5C_ADDR(RS5C372_REG_SECS);
-       buf[1] = BIN2BCD(tm->tm_sec);
-       buf[2] = BIN2BCD(tm->tm_min);
-       buf[3] = rs5c_hr2reg(rs5c, tm->tm_hour);
-       buf[4] = BIN2BCD(tm->tm_wday);
-       buf[5] = BIN2BCD(tm->tm_mday);
-       buf[6] = BIN2BCD(tm->tm_mon + 1);
-       buf[7] = BIN2BCD(tm->tm_year - 100);
+       addr   = RS5C_ADDR(RS5C372_REG_SECS);
+       buf[0] = BIN2BCD(tm->tm_sec);
+       buf[1] = BIN2BCD(tm->tm_min);
+       buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour);
+       buf[3] = BIN2BCD(tm->tm_wday);
+       buf[4] = BIN2BCD(tm->tm_mday);
+       buf[5] = BIN2BCD(tm->tm_mon + 1);
+       buf[6] = BIN2BCD(tm->tm_year - 100);
 
-       if ((i2c_master_send(client, buf, 8)) != 8) {
+       if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) {
                dev_err(&client->dev, "%s: write error\n", __func__);
                return -EIO;
        }
@@ -266,16 +287,16 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
        struct i2c_client       *client = to_i2c_client(dev);
        struct rs5c372          *rs5c = i2c_get_clientdata(client);
-       unsigned char           buf[2];
-       int                     status;
+       unsigned char           buf;
+       int                     status, addr;
 
-       buf[1] = rs5c->regs[RS5C_REG_CTRL1];
+       buf = rs5c->regs[RS5C_REG_CTRL1];
        switch (cmd) {
        case RTC_UIE_OFF:
        case RTC_UIE_ON:
                /* some 327a modes use a different IRQ pin for 1Hz irqs */
                if (rs5c->type == rtc_rs5c372a
-                               && (buf[1] & RS5C372A_CTRL1_SL1))
+                               && (buf & RS5C372A_CTRL1_SL1))
                        return -ENOIOCTLCMD;
        case RTC_AIE_OFF:
        case RTC_AIE_ON:
@@ -293,28 +314,30 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        if (status < 0)
                return status;
 
-       buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
+       addr = RS5C_ADDR(RS5C_REG_CTRL1);
        switch (cmd) {
        case RTC_AIE_OFF:       /* alarm off */
-               buf[1] &= ~RS5C_CTRL1_AALE;
+               buf &= ~RS5C_CTRL1_AALE;
                break;
        case RTC_AIE_ON:        /* alarm on */
-               buf[1] |= RS5C_CTRL1_AALE;
+               buf |= RS5C_CTRL1_AALE;
                break;
        case RTC_UIE_OFF:       /* update off */
-               buf[1] &= ~RS5C_CTRL1_CT_MASK;
+               buf &= ~RS5C_CTRL1_CT_MASK;
                break;
        case RTC_UIE_ON:        /* update on */
-               buf[1] &= ~RS5C_CTRL1_CT_MASK;
-               buf[1] |= RS5C_CTRL1_CT4;
+               buf &= ~RS5C_CTRL1_CT_MASK;
+               buf |= RS5C_CTRL1_CT4;
                break;
        }
-       if ((i2c_master_send(client, buf, 2)) != 2) {
+
+       if (i2c_smbus_write_byte_data(client, addr, buf) < 0) {
                printk(KERN_WARNING "%s: can't update alarm\n",
                        rs5c->rtc->name);
                status = -EIO;
        } else
-               rs5c->regs[RS5C_REG_CTRL1] = buf[1];
+               rs5c->regs[RS5C_REG_CTRL1] = buf;
+
        return status;
 }
 
@@ -364,8 +387,8 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
        struct i2c_client       *client = to_i2c_client(dev);
        struct rs5c372          *rs5c = i2c_get_clientdata(client);
-       int                     status;
-       unsigned char           buf[4];
+       int                     status, addr, i;
+       unsigned char           buf[3];
 
        /* only handle up to 24 hours in the future, like RTC_ALM_SET */
        if (t->time.tm_mday != -1
@@ -380,33 +403,36 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        if (status < 0)
                return status;
        if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) {
-               buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
-               buf[1] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE;
-               if (i2c_master_send(client, buf, 2) != 2) {
+               addr = RS5C_ADDR(RS5C_REG_CTRL1);
+               buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE;
+               if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) {
                        pr_debug("%s: can't disable alarm\n", rs5c->rtc->name);
                        return -EIO;
                }
-               rs5c->regs[RS5C_REG_CTRL1] = buf[1];
+               rs5c->regs[RS5C_REG_CTRL1] = buf[0];
        }
 
        /* set alarm */
-       buf[0] = RS5C_ADDR(RS5C_REG_ALARM_A_MIN);
-       buf[1] = BIN2BCD(t->time.tm_min);
-       buf[2] = rs5c_hr2reg(rs5c, t->time.tm_hour);
-       buf[3] = 0x7f;  /* any/all days */
-       if ((i2c_master_send(client, buf, 4)) != 4) {
-               pr_debug("%s: can't set alarm time\n", rs5c->rtc->name);
-               return -EIO;
+       buf[0] = BIN2BCD(t->time.tm_min);
+       buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
+       buf[2] = 0x7f;  /* any/all days */
+
+       for (i = 0; i < sizeof(buf); i++) {
+               addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
+               if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) {
+                       pr_debug("%s: can't set alarm time\n", rs5c->rtc->name);
+                       return -EIO;
+               }
        }
 
        /* ... and maybe enable its irq */
        if (t->enabled) {
-               buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
-               buf[1] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE;
-               if ((i2c_master_send(client, buf, 2)) != 2)
+               addr = RS5C_ADDR(RS5C_REG_CTRL1);
+               buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE;
+               if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0)
                        printk(KERN_WARNING "%s: can't enable alarm\n",
                                rs5c->rtc->name);
-               rs5c->regs[RS5C_REG_CTRL1] = buf[1];
+               rs5c->regs[RS5C_REG_CTRL1] = buf[0];
        }
 
        return 0;
@@ -503,18 +529,81 @@ static void rs5c_sysfs_unregister(struct device *dev)
 
 static struct i2c_driver rs5c372_driver;
 
+static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
+{
+       unsigned char buf[2];
+       int addr, i, ret = 0;
+
+       if (rs5c372->type == rtc_r2025sd) {
+               if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST))
+                       return ret;
+               rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST;
+       } else {
+               if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP))
+                       return ret;
+               rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP;
+       }
+
+       addr   = RS5C_ADDR(RS5C_REG_CTRL1);
+       buf[0] = rs5c372->regs[RS5C_REG_CTRL1];
+       buf[1] = rs5c372->regs[RS5C_REG_CTRL2];
+
+       /* use 24hr mode */
+       switch (rs5c372->type) {
+       case rtc_rs5c372a:
+       case rtc_rs5c372b:
+               buf[1] |= RS5C372_CTRL2_24;
+               rs5c372->time24 = 1;
+               break;
+       case rtc_r2025sd:
+       case rtc_rv5c386:
+       case rtc_rv5c387a:
+               buf[0] |= RV5C387_CTRL1_24;
+               rs5c372->time24 = 1;
+               break;
+       default:
+               /* impossible */
+               break;
+       }
+
+       for (i = 0; i < sizeof(buf); i++) {
+               addr = RS5C_ADDR(RS5C_REG_CTRL1 + i);
+               ret = i2c_smbus_write_byte_data(rs5c372->client, addr, buf[i]);
+               if (unlikely(ret < 0))
+                       return ret;
+       }
+
+       rs5c372->regs[RS5C_REG_CTRL1] = buf[0];
+       rs5c372->regs[RS5C_REG_CTRL2] = buf[1];
+
+       return 0;
+}
+
 static int rs5c372_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        int err = 0;
+       int smbus_mode = 0;
        struct rs5c372 *rs5c372;
        struct rtc_time tm;
 
        dev_dbg(&client->dev, "%s\n", __func__);
 
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               err = -ENODEV;
-               goto exit;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+                       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) {
+               /*
+                * If we don't have any master mode adapter, try breaking
+                * it down in to the barest of capabilities.
+                */
+               if (i2c_check_functionality(client->adapter,
+                               I2C_FUNC_SMBUS_BYTE_DATA |
+                               I2C_FUNC_SMBUS_I2C_BLOCK))
+                       smbus_mode = 1;
+               else {
+                       /* Still no good, give up */
+                       err = -ENODEV;
+                       goto exit;
+               }
        }
 
        if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) {
@@ -528,6 +617,7 @@ static int rs5c372_probe(struct i2c_client *client,
 
        /* we read registers 0x0f then 0x00-0x0f; skip the first one */
        rs5c372->regs = &rs5c372->buf[1];
+       rs5c372->smbus = smbus_mode;
 
        err = rs5c_get_regs(rs5c372);
        if (err < 0)
@@ -543,6 +633,7 @@ static int rs5c372_probe(struct i2c_client *client,
                if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24)
                        rs5c372->time24 = 1;
                break;
+       case rtc_r2025sd:
        case rtc_rv5c386:
        case rtc_rv5c387a:
                if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24)
@@ -558,39 +649,14 @@ static int rs5c372_probe(struct i2c_client *client,
 
        /* if the oscillator lost power and no other software (like
         * the bootloader) set it up, do it here.
+        *
+        * The R2025S/D does this a little differently than the other
+        * parts, so we special case that..
         */
-       if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP) {
-               unsigned char buf[3];
-
-               rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP;
-
-               buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
-               buf[1] = rs5c372->regs[RS5C_REG_CTRL1];
-               buf[2] = rs5c372->regs[RS5C_REG_CTRL2];
-
-               /* use 24hr mode */
-               switch (rs5c372->type) {
-               case rtc_rs5c372a:
-               case rtc_rs5c372b:
-                       buf[2] |= RS5C372_CTRL2_24;
-                       rs5c372->time24 = 1;
-                       break;
-               case rtc_rv5c386:
-               case rtc_rv5c387a:
-                       buf[1] |= RV5C387_CTRL1_24;
-                       rs5c372->time24 = 1;
-                       break;
-               default:
-                       /* impossible */
-                       break;
-               }
-
-               if ((i2c_master_send(client, buf, 3)) != 3) {
-                       dev_err(&client->dev, "setup error\n");
-                       goto exit_kfree;
-               }
-               rs5c372->regs[RS5C_REG_CTRL1] = buf[1];
-               rs5c372->regs[RS5C_REG_CTRL2] = buf[2];
+       err = rs5c_oscillator_setup(rs5c372);
+       if (unlikely(err < 0)) {
+               dev_err(&client->dev, "setup error\n");
+               goto exit_kfree;
        }
 
        if (rs5c372_get_datetime(client, &tm) < 0)
@@ -598,6 +664,7 @@ static int rs5c372_probe(struct i2c_client *client,
 
        dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n",
                        ({ char *s; switch (rs5c372->type) {
+                       case rtc_r2025sd:       s = "r2025sd"; break;
                        case rtc_rs5c372a:      s = "rs5c372a"; break;
                        case rtc_rs5c372b:      s = "rs5c372b"; break;
                        case rtc_rv5c386:       s = "rv5c386"; break;
@@ -667,7 +734,8 @@ module_exit(rs5c372_exit);
 
 MODULE_AUTHOR(
                "Pavel Mironchik <pmironchik@optifacio.net>, "
-               "Alessandro Zummo <a.zummo@towertech.it>");
+               "Alessandro Zummo <a.zummo@towertech.it>, "
+               "Paul Mundt <lethal@linux-sh.org>");
 MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
index 1f88e9e914ec97d41c139519ab6e2e34c77ea4e2..fcead4c4cd1f339b59b84de1c2d34ea95f38f9f1 100644 (file)
@@ -257,12 +257,6 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
        spin_unlock_irq(&rtc->lock);
 }
 
-static void sh_rtc_release(struct device *dev)
-{
-       sh_rtc_setpie(dev, 0);
-       sh_rtc_setaie(dev, 0);
-}
-
 static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
 {
        struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -559,7 +553,6 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq)
 }
 
 static struct rtc_class_ops sh_rtc_ops = {
-       .release        = sh_rtc_release,
        .ioctl          = sh_rtc_ioctl,
        .read_time      = sh_rtc_read_time,
        .set_time       = sh_rtc_set_time,
index 31d3c8c28588b9f272104aadd83df86512da2200..9a7e920315fa76c6af27d307c913df0b184dadad 100644 (file)
@@ -215,17 +215,6 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void stk17ta8_rtc_release(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
-       if (pdata->irq >= 0) {
-               pdata->irqen = 0;
-               stk17ta8_rtc_update_alarm(pdata);
-       }
-}
-
 static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd,
                            unsigned long arg)
 {
@@ -254,7 +243,6 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = {
        .set_time       = stk17ta8_rtc_set_time,
        .read_alarm     = stk17ta8_rtc_read_alarm,
        .set_alarm      = stk17ta8_rtc_set_alarm,
-       .release        = stk17ta8_rtc_release,
        .ioctl          = stk17ta8_rtc_ioctl,
 };
 
index 1792b2c0130e2c3948ddab8e4798790a7af7b99c..0b15cf107ec97d9162506d1acc23d678416692a3 100644 (file)
@@ -1168,19 +1168,17 @@ static int raw3270_create_attributes(struct raw3270 *rp)
        if (rc)
                goto out;
 
-       rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev,
-                                            MKDEV(IBM_TTY3270_MAJOR, rp->minor),
-                                            NULL,
-                                            "tty%s", dev_name(&rp->cdev->dev));
+       rp->clttydev = device_create(class3270, &rp->cdev->dev,
+                                    MKDEV(IBM_TTY3270_MAJOR, rp->minor), NULL,
+                                    "tty%s", dev_name(&rp->cdev->dev));
        if (IS_ERR(rp->clttydev)) {
                rc = PTR_ERR(rp->clttydev);
                goto out_ttydev;
        }
 
-       rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev,
-                                            MKDEV(IBM_FS3270_MAJOR, rp->minor),
-                                            NULL,
-                                            "tub%s", dev_name(&rp->cdev->dev));
+       rp->cltubdev = device_create(class3270, &rp->cdev->dev,
+                                    MKDEV(IBM_FS3270_MAJOR, rp->minor), NULL,
+                                    "tub%s", dev_name(&rp->cdev->dev));
        if (!IS_ERR(rp->cltubdev))
                goto out;
 
index 12c2a5aaf31b47e88587957b7f31cb6a24edff7b..ddc914ccea8fccef284bd467cd9a4fe7eb4c625a 100644 (file)
@@ -69,9 +69,9 @@ struct tape_class_device *register_tape_dev(
        if (rc)
                goto fail_with_cdev;
 
-       tcd->class_device = device_create_drvdata(tape_class, device,
-                                                 tcd->char_device->dev,
-                                                 NULL, "%s", tcd->device_name);
+       tcd->class_device = device_create(tape_class, device,
+                                         tcd->char_device->dev, NULL,
+                                         "%s", tcd->device_name);
        rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
        if (rc)
                goto fail_with_cdev;
index 42173cc34610f41417b877387dd052517638b6b8..24762727bc27ff80243951dd47a984128af3ed61 100644 (file)
@@ -747,10 +747,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
                device_unregister(dev);
                return ret;
        }
-       priv->class_device = device_create_drvdata(vmlogrdr_class, dev,
-                                                  MKDEV(vmlogrdr_major,
-                                                        priv->minor_num),
-                                                  priv, "%s", dev_name(dev));
+       priv->class_device = device_create(vmlogrdr_class, dev,
+                                          MKDEV(vmlogrdr_major,
+                                                priv->minor_num),
+                                          priv, "%s", dev_name(dev));
        if (IS_ERR(priv->class_device)) {
                ret = PTR_ERR(priv->class_device);
                priv->class_device=NULL;
index 6fdfa5ddeca8f686938f0b52d4bb28b504bfcddc..9020eba620eee22fe8ae36bd0716596c38ae9a7f 100644 (file)
@@ -896,9 +896,8 @@ static int ur_set_online(struct ccw_device *cdev)
                goto fail_free_cdev;
        }
 
-       urd->device = device_create_drvdata(vmur_class, NULL,
-                                           urd->char_device->dev, NULL,
-                                           "%s", node_id);
+       urd->device = device_create(vmur_class, NULL, urd->char_device->dev,
+                                   NULL, "%s", node_id);
        if (IS_ERR(urd->device)) {
                rc = PTR_ERR(urd->device);
                TRACE("ur_set_online: device_create rc=%d\n", rc);
index cbe470493bf01487c6e99ff09f51945732dcfbb3..19f5d5ed85e087b73cce2e24db1bcbc8d92d6a02 100644 (file)
@@ -1673,7 +1673,7 @@ static int mpc_validate_xid(struct mpcg_info *mpcginfo)
 
 done:
        if (rc) {
-               ctcm_pr_info("ctcmpc       :  %s() failed\n", __FUNCTION__);
+               ctcm_pr_info("ctcmpc       :  %s() failed\n", __func__);
                priv->xid->xid2_flag2 = 0x40;
                grp->saved_xid2->xid2_flag2 = 0x40;
        }
index 3c257fe0893e51c9740f226b752a559321cb95a4..88ecf94ad979f92d737fb24adb25ef0fe2a58125 100644 (file)
@@ -914,9 +914,9 @@ static int ch_probe(struct device *dev)
        ch->minor = minor;
        sprintf(ch->name,"ch%d",ch->minor);
 
-       class_dev = device_create_drvdata(ch_sysfs_class, dev,
-                                         MKDEV(SCSI_CHANGER_MAJOR, ch->minor),
-                                         ch, "s%s", ch->name);
+       class_dev = device_create(ch_sysfs_class, dev,
+                                 MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
+                                 "s%s", ch->name);
        if (IS_ERR(class_dev)) {
                printk(KERN_WARNING "ch%d: device_create failed\n",
                       ch->minor);
index 1fe0901e81192d91dad44c4773908c1f6492d39a..8aba4fdfb5222b40d93a8e231fd1b69858ddecdc 100644 (file)
@@ -271,7 +271,7 @@ rebuild_sys_tab:
                pHba->initialized = TRUE;
                pHba->state &= ~DPTI_STATE_RESET;
                if (adpt_sysfs_class) {
-                       struct device *dev = device_create_drvdata(adpt_sysfs_class,
+                       struct device *dev = device_create(adpt_sysfs_class,
                                NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
                                "dpti%d", pHba->unit);
                        if (IS_ERR(dev)) {
index 1c79f9794f4e82bf1e5f30da63bda2b9ace3418b..0ea78d9a37db1a6b0da5b0a18f93fba2aa826a4e 100644 (file)
@@ -5708,7 +5708,8 @@ static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * S
        struct device *osst_member;
        int err;
 
-       osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name);
+       osst_member = device_create(osst_sysfs_class, device, dev, STp,
+                                   "%s", name);
        if (IS_ERR(osst_member)) {
                printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
                return PTR_ERR(osst_member);
index ba9b9bbd4e7385e8d83f3ed4f4a1151b96ab3a1f..93bd59a1ed79b80bde26a459b45b0a0d40ae7f83 100644 (file)
@@ -1450,12 +1450,10 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
        if (sg_sysfs_valid) {
                struct device *sg_class_member;
 
-               sg_class_member = device_create_drvdata(sg_sysfs_class,
-                                                       cl_dev->parent,
-                                                       MKDEV(SCSI_GENERIC_MAJOR,
-                                                             sdp->index),
-                                                       sdp,
-                                                       "%s", disk->disk_name);
+               sg_class_member = device_create(sg_sysfs_class, cl_dev->parent,
+                                               MKDEV(SCSI_GENERIC_MAJOR,
+                                                     sdp->index),
+                                               sdp, "%s", disk->disk_name);
                if (IS_ERR(sg_class_member)) {
                        printk(KERN_ERR "sg_add: "
                               "device_create failed\n");
index c2bb53e3d941faee5d29f5902ac757093102d772..5c28d08f18f46a1bc3f28c5451f84606af747f7c 100644 (file)
@@ -4428,13 +4428,10 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                snprintf(name, 10, "%s%s%s", rew ? "n" : "",
                         STp->disk->disk_name, st_formats[i]);
                st_class_member =
-                       device_create_drvdata(st_sysfs_class,
-                                             &STp->device->sdev_gendev,
-                                             MKDEV(SCSI_TAPE_MAJOR,
-                                                   TAPE_MINOR(dev_num,
-                                                             mode, rew)),
-                                             &STp->modes[mode],
-                                             "%s", name);
+                       device_create(st_sysfs_class, &STp->device->sdev_gendev,
+                                     MKDEV(SCSI_TAPE_MAJOR,
+                                           TAPE_MINOR(dev_num, mode, rew)),
+                                     &STp->modes[mode], "%s", name);
                if (IS_ERR(st_class_member)) {
                        printk(KERN_WARNING "st%d: device_create failed\n",
                               dev_num);
index d3ca7d32abe0ef654f46f9bfd8b6cd00ad977557..1528de23a6504987f78038db7be1e933e4762364 100644 (file)
@@ -2223,9 +2223,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
                serial_outp(up, UART_EFR, efr);
        }
 
-#ifdef CONFIG_ARCH_OMAP15XX
+#ifdef CONFIG_ARCH_OMAP
        /* Workaround to enable 115200 baud on OMAP1510 internal ports */
-       if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+       if (cpu_is_omap1510() && is_omap_port(up)) {
                if (baud == 115200) {
                        quot = 1;
                        serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
@@ -2278,18 +2278,27 @@ serial8250_pm(struct uart_port *port, unsigned int state,
                p->pm(port, state, oldstate);
 }
 
+static unsigned int serial8250_port_size(struct uart_8250_port *pt)
+{
+       if (pt->port.iotype == UPIO_AU)
+               return 0x100000;
+#ifdef CONFIG_ARCH_OMAP
+       if (is_omap_port(pt))
+               return 0x16 << pt->port.regshift;
+#endif
+       return 8 << pt->port.regshift;
+}
+
 /*
  * Resource handling.
  */
 static int serial8250_request_std_resource(struct uart_8250_port *up)
 {
-       unsigned int size = 8 << up->port.regshift;
+       unsigned int size = serial8250_port_size(up);
        int ret = 0;
 
        switch (up->port.iotype) {
        case UPIO_AU:
-               size = 0x100000;
-               /* fall thru */
        case UPIO_TSI:
        case UPIO_MEM32:
        case UPIO_MEM:
@@ -2323,12 +2332,10 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
 
 static void serial8250_release_std_resource(struct uart_8250_port *up)
 {
-       unsigned int size = 8 << up->port.regshift;
+       unsigned int size = serial8250_port_size(up);
 
        switch (up->port.iotype) {
        case UPIO_AU:
-               size = 0x100000;
-               /* fall thru */
        case UPIO_TSI:
        case UPIO_MEM32:
        case UPIO_MEM:
index 31786b3b0a68673b0d4bba4a1711f4c05b3c5518..db783b77a881b9a74cbf298f3442433a6b5eeb4c 100644 (file)
@@ -1123,42 +1123,6 @@ config SERIAL_CPM_CONSOLE
          your boot loader (lilo or loadlin) about how to pass options to the
          kernel at boot time.)
 
-config SERIAL_CPM_SCC1
-       bool "Support for SCC1 serial port"
-       depends on SERIAL_CPM=y
-       help
-         Select this option to use SCC1 as a serial port
-
-config SERIAL_CPM_SCC2
-       bool "Support for SCC2 serial port"
-       depends on SERIAL_CPM=y
-       help
-         Select this option to use SCC2 as a serial port
-
-config SERIAL_CPM_SCC3
-       bool "Support for SCC3 serial port"
-       depends on SERIAL_CPM=y
-       help
-         Select this option to use SCC3 as a serial port
-
-config SERIAL_CPM_SCC4
-       bool "Support for SCC4 serial port"
-       depends on SERIAL_CPM=y
-       help
-         Select this option to use SCC4 as a serial port
-
-config SERIAL_CPM_SMC1
-       bool "Support for SMC1 serial port"
-       depends on SERIAL_CPM=y
-       help
-         Select this option to use SMC1 as a serial port
-
-config SERIAL_CPM_SMC2
-       bool "Support for SMC2 serial port"
-       depends on SERIAL_CPM=y
-       help
-         Select this option to use SMC2 as a serial port
-
 config SERIAL_SGI_L1_CONSOLE
        bool "SGI Altix L1 serial console support"
        depends on IA64_GENERIC || IA64_SGI_SN2
index 25efca5a7a1ffe423b0757f2a89f660390537e20..a6c4d744495e3b694894c35453bbac4a0baff512 100644 (file)
@@ -1333,6 +1333,9 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev,
        if (ret)
                return ret;
 
+       /* initialize the device pointer for the port */
+       pinfo->port.dev = &ofdev->dev;
+
        return uart_add_one_port(&cpm_reg, &pinfo->port);
 }
 
index 0f0aff06c596cf60fc6207c591fd96bda14d370d..1b94c56ec23914a0c7a44acd04ebe61594f39273 100644 (file)
@@ -100,7 +100,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
                mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
                dma_addr = (u32)cpm_dpram_phys(mem_addr);
        } else
-               mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
+               mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr,
                                              GFP_KERNEL);
 
        if (mem_addr == NULL) {
@@ -127,8 +127,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
 
 void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
 {
-       dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
-                                              pinfo->rx_fifosize) +
+       dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
+                                                         pinfo->rx_fifosize) +
                          L1_CACHE_ALIGN(pinfo->tx_nrfifos *
                                         pinfo->tx_fifosize), pinfo->mem_addr,
                          pinfo->dma_addr);
index b8db4d3eed3686ec758e9a11ad783e83c3e0d7b7..141c0a3333ad3c8ac8140b5c52b5588a21daf6b2 100644 (file)
@@ -136,7 +136,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
                dma_addr = virt_to_bus(mem_addr);
        }
        else
-               mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
+               mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr,
                                              GFP_KERNEL);
 
        if (mem_addr == NULL) {
@@ -163,8 +163,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
 
 void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
 {
-       dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
-                                              pinfo->rx_fifosize) +
+       dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
+                                                         pinfo->rx_fifosize) +
                          L1_CACHE_ALIGN(pinfo->tx_nrfifos *
                                         pinfo->tx_fifosize), (void __force *)pinfo->mem_addr,
                          pinfo->dma_addr);
index 36126070d9af8ad10071600b4d53bdb9d947d661..6117d3db0b668980618991a2f66f578410f6e1a7 100644 (file)
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-
-#if defined(CONFIG_PPC_MERGE)
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#else
-#include <linux/platform_device.h>
-#endif
 
 #include <asm/mpc52xx.h>
 #include <asm/mpc512x.h>
@@ -107,12 +102,11 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM];
         *        it's cleared, then a memset(...,0,...) should be added to
         *        the console_init
         */
-#if defined(CONFIG_PPC_MERGE)
+
 /* lookup table for matching device nodes to index numbers */
 static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM];
 
 static void mpc52xx_uart_of_enumerate(void);
-#endif
 
 
 #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
@@ -255,17 +249,12 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port)
 /* Search for bus-frequency property in this node or a parent */
 static unsigned long mpc52xx_getuartclk(void *p)
 {
-#if defined(CONFIG_PPC_MERGE)
        /*
         * 5200 UARTs have a / 32 prescaler
         * but the generic serial code assumes 16
         * so return ipb freq / 2
         */
        return mpc52xx_find_ipb_freq(p) / 2;
-#else
-       pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n");
-       return NULL;
-#endif
 }
 
 static struct psc_ops mpc52xx_psc_ops = {
@@ -886,10 +875,6 @@ mpc52xx_console_get_options(struct uart_port *port,
 
        /* CT{U,L}R are write-only ! */
        *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
-#if !defined(CONFIG_PPC_MERGE)
-       if (__res.bi_baudrate)
-               *baud = __res.bi_baudrate;
-#endif
 
        /* Parse them */
        switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) {
@@ -946,42 +931,6 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
        psc_ops->cw_restore_ints(port);
 }
 
-#if !defined(CONFIG_PPC_MERGE)
-static int __init
-mpc52xx_console_setup(struct console *co, char *options)
-{
-       struct uart_port *port = &mpc52xx_uart_ports[co->index];
-
-       int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
-       int bits = 8;
-       int parity = 'n';
-       int flow = 'n';
-
-       if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM)
-               return -EINVAL;
-
-       /* Basic port init. Needed since we use some uart_??? func before
-        * real init for early access */
-       spin_lock_init(&port->lock);
-       port->uartclk   = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
-       port->ops       = &mpc52xx_uart_ops;
-       port->mapbase   = MPC52xx_PA(MPC52xx_PSCx_OFFSET(co->index+1));
-
-       /* We ioremap ourself */
-       port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
-       if (port->membase == NULL)
-               return -EINVAL;
-
-       /* Setup the port parameters accoding to options */
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
-       else
-               mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow);
-
-       return uart_set_options(port, co, baud, parity, bits, flow);
-}
-
-#else
 
 static int __init
 mpc52xx_console_setup(struct console *co, char *options)
@@ -1053,7 +1002,6 @@ mpc52xx_console_setup(struct console *co, char *options)
 
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
-#endif /* defined(CONFIG_PPC_MERGE) */
 
 
 static struct uart_driver mpc52xx_uart_driver;
@@ -1072,9 +1020,7 @@ static struct console mpc52xx_console = {
 static int __init
 mpc52xx_console_init(void)
 {
-#if defined(CONFIG_PPC_MERGE)
        mpc52xx_uart_of_enumerate();
-#endif
        register_console(&mpc52xx_console);
        return 0;
 }
@@ -1100,115 +1046,6 @@ static struct uart_driver mpc52xx_uart_driver = {
        .cons           = MPC52xx_PSC_CONSOLE,
 };
 
-
-#if !defined(CONFIG_PPC_MERGE)
-/* ======================================================================== */
-/* Platform Driver                                                          */
-/* ======================================================================== */
-
-static int __devinit
-mpc52xx_uart_probe(struct platform_device *dev)
-{
-       struct resource *res = dev->resource;
-
-       struct uart_port *port = NULL;
-       int i, idx, ret;
-
-       /* Check validity & presence */
-       idx = dev->id;
-       if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
-               return -EINVAL;
-
-       if (!mpc52xx_match_psc_function(idx, "uart"))
-               return -ENODEV;
-
-       /* Init the port structure */
-       port = &mpc52xx_uart_ports[idx];
-
-       spin_lock_init(&port->lock);
-       port->uartclk   = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
-       port->fifosize  = 512;
-       port->iotype    = UPIO_MEM;
-       port->flags     = UPF_BOOT_AUTOCONF |
-                         (uart_console(port) ? 0 : UPF_IOREMAP);
-       port->line      = idx;
-       port->ops       = &mpc52xx_uart_ops;
-       port->dev       = &dev->dev;
-
-       /* Search for IRQ and mapbase */
-       for (i = 0 ; i < dev->num_resources ; i++, res++) {
-               if (res->flags & IORESOURCE_MEM)
-                       port->mapbase = res->start;
-               else if (res->flags & IORESOURCE_IRQ)
-                       port->irq = res->start;
-       }
-       if (!port->irq || !port->mapbase)
-               return -EINVAL;
-
-       /* Add the port to the uart sub-system */
-       ret = uart_add_one_port(&mpc52xx_uart_driver, port);
-       if (!ret)
-               platform_set_drvdata(dev, (void *)port);
-
-       return ret;
-}
-
-static int
-mpc52xx_uart_remove(struct platform_device *dev)
-{
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
-
-       platform_set_drvdata(dev, NULL);
-
-       if (port)
-               uart_remove_one_port(&mpc52xx_uart_driver, port);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int
-mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
-{
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
-
-       if (port)
-               uart_suspend_port(&mpc52xx_uart_driver, port);
-
-       return 0;
-}
-
-static int
-mpc52xx_uart_resume(struct platform_device *dev)
-{
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
-
-       if (port)
-               uart_resume_port(&mpc52xx_uart_driver, port);
-
-       return 0;
-}
-#endif
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:mpc52xx-psc");
-
-static struct platform_driver mpc52xx_uart_platform_driver = {
-       .probe          = mpc52xx_uart_probe,
-       .remove         = mpc52xx_uart_remove,
-#ifdef CONFIG_PM
-       .suspend        = mpc52xx_uart_suspend,
-       .resume         = mpc52xx_uart_resume,
-#endif
-       .driver         = {
-               .owner  = THIS_MODULE,
-               .name   = "mpc52xx-psc",
-       },
-};
-#endif /* !defined(CONFIG_PPC_MERGE) */
-
-
-#if defined(CONFIG_PPC_MERGE)
 /* ======================================================================== */
 /* OF Platform Driver                                                       */
 /* ======================================================================== */
@@ -1402,7 +1239,6 @@ static struct of_platform_driver mpc52xx_uart_of_driver = {
                .name   = "mpc52xx-psc-uart",
        },
 };
-#endif /* defined(CONFIG_PPC_MERGE) */
 
 
 /* ======================================================================== */
@@ -1423,7 +1259,6 @@ mpc52xx_uart_init(void)
                return ret;
        }
 
-#if defined(CONFIG_PPC_MERGE)
        mpc52xx_uart_of_enumerate();
 
        ret = of_register_platform_driver(&mpc52xx_uart_of_driver);
@@ -1433,16 +1268,6 @@ mpc52xx_uart_init(void)
                uart_unregister_driver(&mpc52xx_uart_driver);
                return ret;
        }
-#else
-       psc_ops = &mpc52xx_psc_ops;
-       ret = platform_driver_register(&mpc52xx_uart_platform_driver);
-       if (ret) {
-               printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
-                      __FILE__, ret);
-               uart_unregister_driver(&mpc52xx_uart_driver);
-               return ret;
-       }
-#endif
 
        return 0;
 }
@@ -1450,11 +1275,7 @@ mpc52xx_uart_init(void)
 static void __exit
 mpc52xx_uart_exit(void)
 {
-#if defined(CONFIG_PPC_MERGE)
        of_unregister_platform_driver(&mpc52xx_uart_of_driver);
-#else
-       platform_driver_unregister(&mpc52xx_uart_platform_driver);
-#endif
        uart_unregister_driver(&mpc52xx_uart_driver);
 }
 
index c8b4266ac35fdad490af228ae86479cac300b1a3..4873f2978bd2357e9a23b9f5ae745d7f0baa5cdd 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
 #include "samsung.h"
index 40a2531b55410897ec5d744b0931943e33caec23..87c182ef71b8662e4e6de1772cb2ada44b96b235 100644 (file)
@@ -21,7 +21,7 @@
 #include <asm/irq.h>
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
 #include "samsung.h"
index d0170319c729b6cf847ba2e33cd34754b44bc0e4..fd017b37556868ca2268d28101770e028d6538b0 100644 (file)
@@ -21,7 +21,7 @@
 #include <asm/irq.h>
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
 #include "samsung.h"
index d4a2b17b24985fe350352e389ccb42a836dcd2ad..317d239ab74043cf10ada65e9329d4da0d3e87fe 100644 (file)
@@ -21,7 +21,7 @@
 #include <asm/irq.h>
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
 #include "samsung.h"
index 5a88b3f9fe9b676d1b04a175ca7801c0de447b16..1e219d3d0352b29499c60086000b149ad8a902af 100644 (file)
@@ -47,7 +47,7 @@
 
 #include <mach/hardware.h>
 
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
 #include "samsung.h"
index 5c5d18dcb6aca4b0443b9bb8d3d5b2579b5705c0..539c933b335f306b2dc92182785ab09cf271cec6 100644 (file)
@@ -1009,7 +1009,7 @@ static int qe_uart_request_port(struct uart_port *port)
        rx_size = L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize);
        tx_size = L1_CACHE_ALIGN(qe_port->tx_nrfifos * qe_port->tx_fifosize);
 
-       bd_virt = dma_alloc_coherent(NULL, rx_size + tx_size, &bd_dma_addr,
+       bd_virt = dma_alloc_coherent(port->dev, rx_size + tx_size, &bd_dma_addr,
                GFP_KERNEL);
        if (!bd_virt) {
                dev_err(port->dev, "could not allocate buffer descriptors\n");
@@ -1051,7 +1051,7 @@ static void qe_uart_release_port(struct uart_port *port)
                container_of(port, struct uart_qe_port, port);
        struct ucc_slow_private *uccs = qe_port->us_private;
 
-       dma_free_coherent(NULL, qe_port->bd_size, qe_port->bd_virt,
+       dma_free_coherent(port->dev, qe_port->bd_size, qe_port->bd_virt,
                          qe_port->bd_dma_addr);
 
        ucc_slow_free(uccs);
index 25eda71f4bf4c29c442633c5ff2914dad2839e5a..0debe11b67b494a2f0ea4d49cb95598e43217c3d 100644 (file)
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-
-#if defined(CONFIG_PPC_MERGE)
 #include <linux/of_platform.h>
-#else
-#include <linux/platform_device.h>
-#endif
-
 #include <linux/workqueue.h>
 #include <linux/completion.h>
 #include <linux/io.h>
@@ -108,13 +102,13 @@ static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
         * Because psc->ccr is defined as 16bit register instead of 32bit
         * just set the lower byte of BitClkDiv
         */
-       ccr = in_be16(&psc->ccr);
+       ccr = in_be16((u16 __iomem *)&psc->ccr);
        ccr &= 0xFF00;
        if (cs->speed_hz)
                ccr |= (MCLK / cs->speed_hz - 1) & 0xFF;
        else /* by default SPI Clk 1MHz */
                ccr |= (MCLK / 1000000 - 1) & 0xFF;
-       out_be16(&psc->ccr, ccr);
+       out_be16((u16 __iomem *)&psc->ccr, ccr);
        mps->bits_per_word = cs->bits_per_word;
 
        if (mps->activate_cs)
@@ -347,7 +341,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
        /* Configure 8bit codec mode as a SPI master and use EOF flags */
        /* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */
        out_be32(&psc->sicr, 0x0180C800);
-       out_be16(&psc->ccr, 0x070F); /* by default SPI Clk 1MHz */
+       out_be16((u16 __iomem *)&psc->ccr, 0x070F); /* default SPI Clk 1MHz */
 
        /* Set 2ms DTL delay */
        out_8(&psc->ctur, 0x00);
@@ -471,53 +465,6 @@ static int __exit mpc52xx_psc_spi_do_remove(struct device *dev)
        return 0;
 }
 
-#if !defined(CONFIG_PPC_MERGE)
-static int __init mpc52xx_psc_spi_probe(struct platform_device *dev)
-{
-       switch(dev->id) {
-       case 1:
-       case 2:
-       case 3:
-       case 6:
-               return mpc52xx_psc_spi_do_probe(&dev->dev,
-                       MPC52xx_PA(MPC52xx_PSCx_OFFSET(dev->id)),
-                       MPC52xx_PSC_SIZE, platform_get_irq(dev, 0), dev->id);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev)
-{
-       return mpc52xx_psc_spi_do_remove(&dev->dev);
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:mpc52xx-psc-spi");
-
-static struct platform_driver mpc52xx_psc_spi_platform_driver = {
-       .remove = __exit_p(mpc52xx_psc_spi_remove),
-       .driver = {
-               .name = "mpc52xx-psc-spi",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init mpc52xx_psc_spi_init(void)
-{
-       return platform_driver_probe(&mpc52xx_psc_spi_platform_driver,
-                       mpc52xx_psc_spi_probe);
-}
-module_init(mpc52xx_psc_spi_init);
-
-static void __exit mpc52xx_psc_spi_exit(void)
-{
-       platform_driver_unregister(&mpc52xx_psc_spi_platform_driver);
-}
-module_exit(mpc52xx_psc_spi_exit);
-
-#else  /* defined(CONFIG_PPC_MERGE) */
-
 static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
        const struct of_device_id *match)
 {
@@ -586,8 +533,6 @@ static void __exit mpc52xx_psc_spi_exit(void)
 }
 module_exit(mpc52xx_psc_spi_exit);
 
-#endif /* defined(CONFIG_PPC_MERGE) */
-
 MODULE_AUTHOR("Dragos Carp");
 MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");
 MODULE_LICENSE("GPL");
index 9d2186fd74aaf7eaca9f9954dde88d1dc11e7c36..454a2712e6290ee0f0f085667a0baec9ec6bb027 100644 (file)
@@ -119,12 +119,14 @@ struct omap2_mcspi {
        struct clk              *fck;
        /* Virtual base address of the controller */
        void __iomem            *base;
+       unsigned long           phys;
        /* SPI1 has 4 channels, while SPI2 has 2 */
        struct omap2_mcspi_dma  *dma_channels;
 };
 
 struct omap2_mcspi_cs {
        void __iomem            *base;
+       unsigned long           phys;
        int                     word_len;
 };
 
@@ -233,7 +235,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
        c = count;
        word_len = cs->word_len;
 
-       base = (unsigned long) io_v2p(cs->base);
+       base = cs->phys;
        tx_reg = base + OMAP2_MCSPI_TX0;
        rx_reg = base + OMAP2_MCSPI_RX0;
        rx = xfer->rx_buf;
@@ -633,6 +635,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
                if (!cs)
                        return -ENOMEM;
                cs->base = mcspi->base + spi->chip_select * 0x14;
+               cs->phys = mcspi->phys + spi->chip_select * 0x14;
                spi->controller_state = cs;
        }
 
@@ -1005,7 +1008,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
                goto err1;
        }
 
-       mcspi->base = (void __iomem *) io_p2v(r->start);
+       mcspi->phys = r->start;
+       mcspi->base = ioremap(r->start, r->end - r->start + 1);
+       if (!mcspi->base) {
+               dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
+               status = -ENOMEM;
+               goto err1aa;
+       }
 
        INIT_WORK(&mcspi->work, omap2_mcspi_work);
 
@@ -1055,6 +1064,8 @@ err3:
 err2:
        clk_put(mcspi->ick);
 err1a:
+       iounmap(mcspi->base);
+err1aa:
        release_mem_region(r->start, (r->end - r->start) + 1);
 err1:
        spi_master_put(master);
@@ -1067,6 +1078,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
        struct omap2_mcspi      *mcspi;
        struct omap2_mcspi_dma  *dma_channels;
        struct resource         *r;
+       void __iomem *base;
 
        master = dev_get_drvdata(&pdev->dev);
        mcspi = spi_master_get_devdata(master);
@@ -1078,7 +1090,9 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(r->start, (r->end - r->start) + 1);
 
+       base = mcspi->base;
        spi_unregister_master(master);
+       iounmap(base);
        kfree(dma_channels);
 
        return 0;
index 5515eb97d7c57ebacdcc7c4379822af0dd5bb751..bab6ff061e9145a95dad6756d6cbc4b25e69e671 100644 (file)
@@ -59,7 +59,6 @@
  * and irqs should show there too...
  */
 #define UWIRE_BASE_PHYS                0xFFFB3000
-#define UWIRE_BASE             ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS))
 
 /* uWire Registers: */
 #define UWIRE_IO_SIZE 0x20
@@ -103,16 +102,21 @@ struct uwire_state {
 };
 
 /* REVISIT compile time constant for idx_shift? */
+/*
+ * Or, put it in a structure which is used throughout the driver;
+ * that avoids having to issue two loads for each bit of static data.
+ */
 static unsigned int uwire_idx_shift;
+static void __iomem *uwire_base;
 
 static inline void uwire_write_reg(int idx, u16 val)
 {
-       __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift));
+       __raw_writew(val, uwire_base + (idx << uwire_idx_shift));
 }
 
 static inline u16 uwire_read_reg(int idx)
 {
-       return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift));
+       return __raw_readw(uwire_base + (idx << uwire_idx_shift));
 }
 
 static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)
@@ -492,6 +496,14 @@ static int __init uwire_probe(struct platform_device *pdev)
                return -ENODEV;
 
        uwire = spi_master_get_devdata(master);
+
+       uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE);
+       if (!uwire_base) {
+               dev_dbg(&pdev->dev, "can't ioremap UWIRE\n");
+               spi_master_put(master);
+               return -ENOMEM;
+       }
+
        dev_set_drvdata(&pdev->dev, uwire);
 
        uwire->ck = clk_get(&pdev->dev, "armxor_ck");
@@ -520,8 +532,10 @@ static int __init uwire_probe(struct platform_device *pdev)
        uwire->bitbang.txrx_bufs = uwire_txrx;
 
        status = spi_bitbang_start(&uwire->bitbang);
-       if (status < 0)
+       if (status < 0) {
                uwire_off(uwire);
+               iounmap(uwire_base);
+       }
        return status;
 }
 
@@ -534,6 +548,7 @@ static int __exit uwire_remove(struct platform_device *pdev)
 
        status = spi_bitbang_stop(&uwire->bitbang);
        uwire_off(uwire);
+       iounmap(uwire_base);
        return status;
 }
 
index b872bfaf4bd2c0e4706c1551db8da94324622983..014becb7d53007b20099b9b9c84d0eb09d19e5dc 100644 (file)
@@ -364,6 +364,11 @@ static int orion_spi_setup(struct spi_device *spi)
                return -EINVAL;
        }
 
+       /* Fix ac timing if required.   */
+       if (orion_spi->spi_info->enable_clock_fix)
+               orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
+                                 (1 << 14));
+
        if (spi->bits_per_word == 0)
                spi->bits_per_word = 8;
 
index d47d3636227fe90e435fc03a8f59fd49860b1220..dae87b1a4c6effa5c18cff538c3a634a846a2957 100644 (file)
@@ -47,6 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
 
 #define MAX_BUSES 3
 
+#define RX_THRESH_DFLT         8
+#define TX_THRESH_DFLT         8
+#define TIMOUT_DFLT            1000
+
 #define DMA_INT_MASK           (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
 #define RESET_DMA_CHANNEL      (DCSR_NODESC | DMA_INT_MASK)
 #define IS_DMA_ALIGNED(x)      ((((u32)(x)) & 0x07) == 0)
@@ -1171,6 +1175,8 @@ static int setup(struct spi_device *spi)
        struct driver_data *drv_data = spi_master_get_devdata(spi->master);
        struct ssp_device *ssp = drv_data->ssp;
        unsigned int clk_div;
+       uint tx_thres = TX_THRESH_DFLT;
+       uint rx_thres = RX_THRESH_DFLT;
 
        if (!spi->bits_per_word)
                spi->bits_per_word = 8;
@@ -1209,8 +1215,7 @@ static int setup(struct spi_device *spi)
 
                chip->cs_control = null_cs_control;
                chip->enable_dma = 0;
-               chip->timeout = 1000;
-               chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
+               chip->timeout = TIMOUT_DFLT;
                chip->dma_burst_size = drv_data->master_info->enable_dma ?
                                        DCMD_BURST8 : 0;
        }
@@ -1224,22 +1229,21 @@ static int setup(struct spi_device *spi)
        if (chip_info) {
                if (chip_info->cs_control)
                        chip->cs_control = chip_info->cs_control;
-
-               chip->timeout = chip_info->timeout;
-
-               chip->threshold = (SSCR1_RxTresh(chip_info->rx_threshold) &
-                                                               SSCR1_RFT) |
-                               (SSCR1_TxTresh(chip_info->tx_threshold) &
-                                                               SSCR1_TFT);
-
-               chip->enable_dma = chip_info->dma_burst_size != 0
-                                       && drv_data->master_info->enable_dma;
+               if (chip_info->timeout)
+                       chip->timeout = chip_info->timeout;
+               if (chip_info->tx_threshold)
+                       tx_thres = chip_info->tx_threshold;
+               if (chip_info->rx_threshold)
+                       rx_thres = chip_info->rx_threshold;
+               chip->enable_dma = drv_data->master_info->enable_dma;
                chip->dma_threshold = 0;
-
                if (chip_info->enable_loopback)
                        chip->cr1 = SSCR1_LBM;
        }
 
+       chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
+                       (SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
+
        /* set dma burst and threshold outside of chip_info path so that if
         * chip_info goes away after setting chip->enable_dma, the
         * burst and threshold can still respond to changes in bits_per_word */
@@ -1268,17 +1272,19 @@ static int setup(struct spi_device *spi)
 
        /* NOTE:  PXA25x_SSP _could_ use external clocking ... */
        if (drv_data->ssp_type != PXA25x_SSP)
-               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
+               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
                                spi->bits_per_word,
                                clk_get_rate(ssp->clk)
                                        / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-                               spi->mode & 0x3);
+                               spi->mode & 0x3,
+                               chip->enable_dma ? "DMA" : "PIO");
        else
-               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
+               dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
                                spi->bits_per_word,
-                               clk_get_rate(ssp->clk)
+                               clk_get_rate(ssp->clk) / 2
                                        / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-                               spi->mode & 0x3);
+                               spi->mode & 0x3,
+                               chip->enable_dma ? "DMA" : "PIO");
 
        if (spi->bits_per_word <= 8) {
                chip->n_bytes = 1;
@@ -1407,9 +1413,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct pxa2xx_spi_master *platform_info;
        struct spi_master *master;
-       struct driver_data *drv_data = NULL;
+       struct driver_data *drv_data;
        struct ssp_device *ssp;
-       int status = 0;
+       int status;
 
        platform_info = dev->platform_data;
 
@@ -1422,7 +1428,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
        /* Allocate master with space for drv_data and null dma buffer */
        master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
        if (!master) {
-               dev_err(&pdev->dev, "can not alloc spi_master\n");
+               dev_err(&pdev->dev, "cannot alloc spi_master\n");
                ssp_free(ssp);
                return -ENOMEM;
        }
@@ -1458,7 +1464,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
 
        status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
        if (status < 0) {
-               dev_err(&pdev->dev, "can not get IRQ\n");
+               dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq);
                goto out_error_master_alloc;
        }
 
@@ -1498,7 +1504,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
 
        /* Load default SSP configuration */
        write_SSCR0(0, drv_data->ioaddr);
-       write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr);
+       write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
+                               SSCR1_TxTresh(TX_THRESH_DFLT),
+                               drv_data->ioaddr);
        write_SSCR0(SSCR0_SerClkDiv(2)
                        | SSCR0_Motorola
                        | SSCR0_DataSize(8),
index 75e86865234c924a67bb94d39c3fc259a6925b5a..3734dc9708e12669070ab984cc2fe9f0fbee1b70 100644 (file)
@@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_device *spi,
 
        int                     status;
        struct spi_message      message;
-       struct spi_transfer     x[2];
+       struct spi_transfer     x;
        u8                      *local_buf;
 
        /* Use preallocated DMA-safe buffer.  We can't avoid copying here,
@@ -671,15 +671,9 @@ int spi_write_then_read(struct spi_device *spi,
                return -EINVAL;
 
        spi_message_init(&message);
-       memset(x, 0, sizeof x);
-       if (n_tx) {
-               x[0].len = n_tx;
-               spi_message_add_tail(&x[0], &message);
-       }
-       if (n_rx) {
-               x[1].len = n_rx;
-               spi_message_add_tail(&x[1], &message);
-       }
+       memset(&x, 0, sizeof x);
+       x.len = n_tx + n_rx;
+       spi_message_add_tail(&x, &message);
 
        /* ... unless someone else is using the pre-allocated buffer */
        if (!mutex_trylock(&lock)) {
@@ -690,15 +684,15 @@ int spi_write_then_read(struct spi_device *spi,
                local_buf = buf;
 
        memcpy(local_buf, txbuf, n_tx);
-       x[0].tx_buf = local_buf;
-       x[1].rx_buf = local_buf + n_tx;
+       x.tx_buf = local_buf;
+       x.rx_buf = local_buf;
 
        /* do the i/o */
        status = spi_sync(spi, &message);
        if (status == 0)
-               memcpy(rxbuf, x[1].rx_buf, n_rx);
+               memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
 
-       if (x[0].tx_buf == buf)
+       if (x.tx_buf == buf)
                mutex_unlock(&lock);
        else
                kfree(local_buf);
@@ -744,5 +738,5 @@ err0:
  * driver registration) _could_ be dynamically linked (modular) ... costs
  * include needing to have boardinfo data structures be much more public.
  */
-subsys_initcall(spi_init);
+postcore_initcall(spi_init);
 
index 3eb414b84a9d5a2f82482bec675e22c969d4c224..c252cbac00f1d14ef273f53dea2ca7f39edd38b5 100644 (file)
@@ -247,6 +247,9 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
        writeb(0xff, hw->regs + S3C2410_SPPRE);
        writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
        writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
+
+       if (hw->pdata && hw->pdata->gpio_setup)
+               hw->pdata->gpio_setup(hw->pdata, 1);
 }
 
 static int __init s3c24xx_spi_probe(struct platform_device *pdev)
@@ -412,6 +415,9 @@ static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
 {
        struct s3c24xx_spi *hw = platform_get_drvdata(pdev);
 
+       if (hw->pdata && hw->pdata->gpio_setup)
+               hw->pdata->gpio_setup(hw->pdata, 0);
+
        clk_disable(hw->clk);
        return 0;
 }
index e5e0cfed5e3b3fedff7f81983a73f4b94a9de8ca..89a43755a453bb265ebfa789adca222a8cce1ebe 100644 (file)
@@ -583,10 +583,9 @@ static int spidev_probe(struct spi_device *spi)
                struct device *dev;
 
                spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
-               dev = device_create_drvdata(spidev_class, &spi->dev,
-                               spidev->devt, spidev,
-                               "spidev%d.%d",
-                               spi->master->bus_num, spi->chip_select);
+               dev = device_create(spidev_class, &spi->dev, spidev->devt,
+                                   spidev, "spidev%d.%d",
+                                   spi->master->bus_num, spi->chip_select);
                status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
        } else {
                dev_dbg(&spi->dev, "no minor number available!\n");
index ec7aeb502d1548ecbfd64c521518c11857e308de..41b6530b8f251d0a2d5193eb58297ee3a99f30ac 100644 (file)
@@ -42,8 +42,6 @@
  ***************************************************************************/
 
 /*
- * $Log: ixj.c,v $
- *
  * Revision 4.8  2003/07/09 19:39:00  Daniele Bellucci
  * Audit some copy_*_user and minor cleanup.
  *
index 4190be64917f416be6f4809929bf0e23b78a755d..04b954cfce7608827a821138df74db9caccb9f80 100644 (file)
@@ -58,4 +58,17 @@ config UIO_SMX
 
          If you compile this as a module, it will be called uio_smx.
 
+config UIO_SERCOS3
+       tristate "Automata Sercos III PCI card driver"
+       default n
+       help
+         Userspace I/O interface for the Sercos III PCI card from
+         Automata GmbH. The userspace part of this driver will be
+         available for download from the Automata GmbH web site.
+
+         Automata GmbH:        http://www.automataweb.com
+         Sercos III interface: http://www.sercos.com
+
+         If you compile this as a module, it will be called uio_sercos3.
+
 endif
index 8667bbdef904fc3ddd2df2d1208938f5fdcc2a7e..e69558149859f0dd36b1d0433190d6e06773aafa 100644 (file)
@@ -3,3 +3,4 @@ obj-$(CONFIG_UIO_CIF)   += uio_cif.o
 obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
 obj-$(CONFIG_UIO_PDRV_GENIRQ)  += uio_pdrv_genirq.o
 obj-$(CONFIG_UIO_SMX)  += uio_smx.o
+obj-$(CONFIG_UIO_SERCOS3)      += uio_sercos3.o
index 3a6934bf713134edc3f53b68e25bf913ec3215e4..5dccf057a7dd41a5f31f69ec4d5d7982615655ec 100644 (file)
@@ -67,6 +67,11 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf)
        return sprintf(buf, "0x%lx\n", mem->size);
 }
 
+static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
+{
+       return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK);
+}
+
 struct uio_sysfs_entry {
        struct attribute attr;
        ssize_t (*show)(struct uio_mem *, char *);
@@ -77,10 +82,13 @@ static struct uio_sysfs_entry addr_attribute =
        __ATTR(addr, S_IRUGO, map_addr_show, NULL);
 static struct uio_sysfs_entry size_attribute =
        __ATTR(size, S_IRUGO, map_size_show, NULL);
+static struct uio_sysfs_entry offset_attribute =
+       __ATTR(offset, S_IRUGO, map_offset_show, NULL);
 
 static struct attribute *attrs[] = {
        &addr_attribute.attr,
        &size_attribute.attr,
+       &offset_attribute.attr,
        NULL,   /* need to NULL terminate the list of attributes */
 };
 
@@ -482,15 +490,23 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        struct uio_device *idev = vma->vm_private_data;
        struct page *page;
+       unsigned long offset;
 
        int mi = uio_find_mem_index(vma);
        if (mi < 0)
                return VM_FAULT_SIGBUS;
 
+       /*
+        * We need to subtract mi because userspace uses offset = N*PAGE_SIZE
+        * to use mem[N].
+        */
+       offset = (vmf->pgoff - mi) << PAGE_SHIFT;
+
        if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
-               page = virt_to_page(idev->info->mem[mi].addr);
+               page = virt_to_page(idev->info->mem[mi].addr + offset);
        else
-               page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
+               page = vmalloc_to_page((void *)idev->info->mem[mi].addr
+                                                       + offset);
        get_page(page);
        vmf->page = page;
        return 0;
@@ -682,9 +698,9 @@ int __uio_register_device(struct module *owner,
        if (ret)
                goto err_get_minor;
 
-       idev->dev = device_create_drvdata(uio_class->class, parent,
-                                         MKDEV(uio_major, idev->minor), idev,
-                                         "uio%d", idev->minor);
+       idev->dev = device_create(uio_class->class, parent,
+                                 MKDEV(uio_major, idev->minor), idev,
+                                 "uio%d", idev->minor);
        if (IS_ERR(idev->dev)) {
                printk(KERN_ERR "UIO: device register failed\n");
                ret = PTR_ERR(idev->dev);
index 0b4ef39cd85d289d3aee60264dd6044bee1f0b8b..d494ce9288c37e9b59c34962c66b291f7185a313 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/uio_driver.h>
 #include <linux/stringify.h>
 
-#define DRIVER_NAME "uio"
+#define DRIVER_NAME "uio_pdrv"
 
 struct uio_platdata {
        struct uio_info *uioinfo;
diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c
new file mode 100644 (file)
index 0000000..a6d1b2b
--- /dev/null
@@ -0,0 +1,243 @@
+/* sercos3: UIO driver for the Automata Sercos III PCI card
+
+   Copyright (C) 2008 Linutronix GmbH
+     Author: John Ogness <john.ogness@linutronix.de>
+
+   This is a straight-forward UIO driver, where interrupts are disabled
+   by the interrupt handler and re-enabled via a write to the UIO device
+   by the userspace-part.
+
+   The only part that may seem odd is the use of a logical OR when
+   storing and restoring enabled interrupts. This is done because the
+   userspace-part could directly modify the Interrupt Enable Register
+   at any time. To reduce possible conflicts, the kernel driver uses
+   a logical OR to make more controlled changes (rather than blindly
+   overwriting previous values).
+
+   Race conditions exist if the userspace-part directly modifies the
+   Interrupt Enable Register while in operation. The consequences are
+   that certain interrupts would fail to be enabled or disabled. For
+   this reason, the userspace-part should only directly modify the
+   Interrupt Enable Register at the beginning (to get things going).
+   The userspace-part can safely disable interrupts at any time using
+   a write to the UIO device.
+*/
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+#include <linux/io.h>
+
+/* ID's for SERCOS III PCI card (PLX 9030) */
+#define SERCOS_SUB_VENDOR_ID  0x1971
+#define SERCOS_SUB_SYSID_3530 0x3530
+#define SERCOS_SUB_SYSID_3535 0x3535
+#define SERCOS_SUB_SYSID_3780 0x3780
+
+/* Interrupt Enable Register */
+#define IER0_OFFSET 0x08
+
+/* Interrupt Status Register */
+#define ISR0_OFFSET 0x18
+
+struct sercos3_priv {
+       u32 ier0_cache;
+       spinlock_t ier0_cache_lock;
+};
+
+/* this function assumes ier0_cache_lock is locked! */
+static void sercos3_disable_interrupts(struct uio_info *info,
+                                      struct sercos3_priv *priv)
+{
+       void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+       /* add enabled interrupts to cache */
+       priv->ier0_cache |= ioread32(ier0);
+
+       /* disable interrupts */
+       iowrite32(0, ier0);
+}
+
+/* this function assumes ier0_cache_lock is locked! */
+static void sercos3_enable_interrupts(struct uio_info *info,
+                                     struct sercos3_priv *priv)
+{
+       void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+       /* restore previously enabled interrupts */
+       iowrite32(ioread32(ier0) | priv->ier0_cache, ier0);
+       priv->ier0_cache = 0;
+}
+
+static irqreturn_t sercos3_handler(int irq, struct uio_info *info)
+{
+       struct sercos3_priv *priv = info->priv;
+       void __iomem *isr0 = info->mem[3].internal_addr + ISR0_OFFSET;
+       void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+       if (!(ioread32(isr0) & ioread32(ier0)))
+               return IRQ_NONE;
+
+       spin_lock(&priv->ier0_cache_lock);
+       sercos3_disable_interrupts(info, priv);
+       spin_unlock(&priv->ier0_cache_lock);
+
+       return IRQ_HANDLED;
+}
+
+static int sercos3_irqcontrol(struct uio_info *info, s32 irq_on)
+{
+       struct sercos3_priv *priv = info->priv;
+
+       spin_lock_irq(&priv->ier0_cache_lock);
+       if (irq_on)
+               sercos3_enable_interrupts(info, priv);
+       else
+               sercos3_disable_interrupts(info, priv);
+       spin_unlock_irq(&priv->ier0_cache_lock);
+
+       return 0;
+}
+
+static int sercos3_setup_iomem(struct pci_dev *dev, struct uio_info *info,
+                              int n, int pci_bar)
+{
+       info->mem[n].addr = pci_resource_start(dev, pci_bar);
+       if (!info->mem[n].addr)
+               return -1;
+       info->mem[n].internal_addr = ioremap(pci_resource_start(dev, pci_bar),
+                                            pci_resource_len(dev, pci_bar));
+       if (!info->mem[n].internal_addr)
+               return -1;
+       info->mem[n].size = pci_resource_len(dev, pci_bar);
+       info->mem[n].memtype = UIO_MEM_PHYS;
+       return 0;
+}
+
+static int __devinit sercos3_pci_probe(struct pci_dev *dev,
+                                      const struct pci_device_id *id)
+{
+       struct uio_info *info;
+       struct sercos3_priv *priv;
+       int i;
+
+       info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       priv = kzalloc(sizeof(struct sercos3_priv), GFP_KERNEL);
+       if (!priv)
+               goto out_free;
+
+       if (pci_enable_device(dev))
+               goto out_free_priv;
+
+       if (pci_request_regions(dev, "sercos3"))
+               goto out_disable;
+
+       /* we only need PCI BAR's 0, 2, 3, 4, 5 */
+       if (sercos3_setup_iomem(dev, info, 0, 0))
+               goto out_unmap;
+       if (sercos3_setup_iomem(dev, info, 1, 2))
+               goto out_unmap;
+       if (sercos3_setup_iomem(dev, info, 2, 3))
+               goto out_unmap;
+       if (sercos3_setup_iomem(dev, info, 3, 4))
+               goto out_unmap;
+       if (sercos3_setup_iomem(dev, info, 4, 5))
+               goto out_unmap;
+
+       spin_lock_init(&priv->ier0_cache_lock);
+       info->priv = priv;
+       info->name = "Sercos_III_PCI";
+       info->version = "0.0.1";
+       info->irq = dev->irq;
+       info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
+       info->handler = sercos3_handler;
+       info->irqcontrol = sercos3_irqcontrol;
+
+       pci_set_drvdata(dev, info);
+
+       if (uio_register_device(&dev->dev, info))
+               goto out_unmap;
+
+       return 0;
+
+out_unmap:
+       for (i = 0; i < 5; i++) {
+               if (info->mem[i].internal_addr)
+                       iounmap(info->mem[i].internal_addr);
+       }
+       pci_release_regions(dev);
+out_disable:
+       pci_disable_device(dev);
+out_free_priv:
+       kfree(priv);
+out_free:
+       kfree(info);
+       return -ENODEV;
+}
+
+static void sercos3_pci_remove(struct pci_dev *dev)
+{
+       struct uio_info *info = pci_get_drvdata(dev);
+       int i;
+
+       uio_unregister_device(info);
+       pci_release_regions(dev);
+       pci_disable_device(dev);
+       pci_set_drvdata(dev, NULL);
+       for (i = 0; i < 5; i++) {
+               if (info->mem[i].internal_addr)
+                       iounmap(info->mem[i].internal_addr);
+       }
+       kfree(info->priv);
+       kfree(info);
+}
+
+static struct pci_device_id sercos3_pci_ids[] __devinitdata = {
+       {
+               .vendor =       PCI_VENDOR_ID_PLX,
+               .device =       PCI_DEVICE_ID_PLX_9030,
+               .subvendor =    SERCOS_SUB_VENDOR_ID,
+               .subdevice =    SERCOS_SUB_SYSID_3530,
+       },
+       {
+               .vendor =       PCI_VENDOR_ID_PLX,
+               .device =       PCI_DEVICE_ID_PLX_9030,
+               .subvendor =    SERCOS_SUB_VENDOR_ID,
+               .subdevice =    SERCOS_SUB_SYSID_3535,
+       },
+       {
+               .vendor =       PCI_VENDOR_ID_PLX,
+               .device =       PCI_DEVICE_ID_PLX_9030,
+               .subvendor =    SERCOS_SUB_VENDOR_ID,
+               .subdevice =    SERCOS_SUB_SYSID_3780,
+       },
+       { 0, }
+};
+
+static struct pci_driver sercos3_pci_driver = {
+       .name = "sercos3",
+       .id_table = sercos3_pci_ids,
+       .probe = sercos3_pci_probe,
+       .remove = sercos3_pci_remove,
+};
+
+static int __init sercos3_init_module(void)
+{
+       return pci_register_driver(&sercos3_pci_driver);
+}
+
+static void __exit sercos3_exit_module(void)
+{
+       pci_unregister_driver(&sercos3_pci_driver);
+}
+
+module_init(sercos3_init_module);
+module_exit(sercos3_exit_module);
+
+MODULE_DESCRIPTION("UIO driver for the Automata Sercos III PCI card");
+MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>");
+MODULE_LICENSE("GPL v2");
index 20290c5b15625c3b4272765ff95eefa3feb07b88..7a4fa791dc196f18a042e4c203ca21b5a0313e97 100644 (file)
@@ -1729,9 +1729,9 @@ static int usb_classdev_add(struct usb_device *dev)
 {
        struct device *cldev;
 
-       cldev = device_create_drvdata(usb_classdev_class, &dev->dev,
-                                     dev->dev.devt, NULL, "usbdev%d.%d",
-                                     dev->bus->busnum, dev->devnum);
+       cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt,
+                             NULL, "usbdev%d.%d", dev->bus->busnum,
+                             dev->devnum);
        if (IS_ERR(cldev))
                return PTR_ERR(cldev);
        dev->usb_classdev = cldev;
index 6b1b229e38cd1d28790d5f29e54eebbe3efe2fb8..55f7f310924b99f434ba6201525c2b85b48e27ba 100644 (file)
@@ -196,9 +196,9 @@ int usb_register_dev(struct usb_interface *intf,
                ++temp;
        else
                temp = name;
-       intf->usb_dev = device_create_drvdata(usb_class->class, &intf->dev,
-                                             MKDEV(USB_MAJOR, minor), NULL,
-                                             "%s", temp);
+       intf->usb_dev = device_create(usb_class->class, &intf->dev,
+                                     MKDEV(USB_MAJOR, minor), NULL,
+                                     "%s", temp);
        if (IS_ERR(intf->usb_dev)) {
                down_write(&minor_rwsem);
                usb_minors[intf->minor] = NULL;
index 8ab389dca2b91c49bfdb75e900a1c5a5dde3d334..c8035a8216bdb5017435c7ad49a5d555b2cce8e9 100644 (file)
@@ -818,9 +818,8 @@ static int usb_register_bus(struct usb_bus *bus)
        set_bit (busnum, busmap.busmap);
        bus->busnum = busnum;
 
-       bus->dev = device_create_drvdata(usb_host_class, bus->controller,
-                                        MKDEV(0, 0), bus,
-                                        "usb_host%d", busnum);
+       bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0),
+                                bus, "usb_host%d", busnum);
        result = PTR_ERR(bus->dev);
        if (IS_ERR(bus->dev))
                goto error_create_class_dev;
index fcb5cb9094d905d7e26c35a7dae074fc28b633bd..2267fa0b51b20e28e230b9cd5a802a9b3ea44f5f 100644 (file)
@@ -22,24 +22,15 @@ obj-$(CONFIG_USB_M66592)    += m66592-udc.o
 #
 # USB gadget drivers
 #
-C_UTILS =      composite.o usbstring.o config.o epautoconf.o
-
-g_zero-objs                    := zero.o f_sourcesink.o f_loopback.o $(C_UTILS)
-g_ether-objs                   := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS)
-g_serial-objs                  := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS)
-g_midi-objs                    := gmidi.o usbstring.o config.o epautoconf.o
+g_zero-objs                    := zero.o
+g_ether-objs                   := ether.o
+g_serial-objs                  := serial.o
+g_midi-objs                    := gmidi.o
 gadgetfs-objs                  := inode.o
-g_file_storage-objs            := file_storage.o usbstring.o config.o \
-                                       epautoconf.o
-g_printer-objs                 := printer.o usbstring.o config.o \
-                                       epautoconf.o
-g_cdc-objs                     := cdc2.o u_ether.o f_ecm.o \
-                                       u_serial.o f_acm.o $(C_UTILS)
+g_file_storage-objs            := file_storage.o
+g_printer-objs                 := printer.o
+g_cdc-objs                     := cdc2.o
 
-ifeq ($(CONFIG_USB_ETH_RNDIS),y)
-       g_ether-objs            += f_rndis.o rndis.o
-endif
 obj-$(CONFIG_USB_ZERO)         += g_zero.o
 obj-$(CONFIG_USB_ETH)          += g_ether.o
 obj-$(CONFIG_USB_GADGETFS)     += gadgetfs.o
index a39a4b940c33c93aa129fb5aab06fd4c326e556d..a724fc149850ad30deef93e73b6da96879cadd99 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+#include "u_serial.c"
+#include "f_acm.c"
+#include "f_ecm.c"
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
 static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
@@ -148,7 +167,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
        int                     status;
 
        if (!can_support_ecm(cdev->gadget)) {
-               ERROR(cdev, "controller '%s' not usable\n", gadget->name);
+               dev_err(&gadget->dev, "controller '%s' not usable\n",
+                               gadget->name);
                return -EINVAL;
        }
 
@@ -203,7 +223,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
        if (status < 0)
                goto fail1;
 
-       INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+       dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+                       DRIVER_DESC);
 
        return 0;
 
index bcac2e68660d5ba51fd8c253fa136c4385e9c058..944c8e889ab4368bae56b96a679aeb590323648a 100644 (file)
@@ -96,6 +96,28 @@ static inline bool has_rndis(void)
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_ecm.c"
+#include "f_subset.c"
+#ifdef CONFIG_USB_ETH_RNDIS
+#include "f_rndis.c"
+#include "rndis.c"
+#endif
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
 /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
  * Instead:  allocate your own, using normal USB-IF procedures.
  */
@@ -293,7 +315,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
                 * but if the controller isn't recognized at all then
                 * that assumption is a bit more likely to be wrong.
                 */
-               WARNING(cdev, "controller '%s' not recognized; trying %s\n",
+               dev_warn(&gadget->dev,
+                               "controller '%s' not recognized; trying %s\n",
                                gadget->name,
                                eth_config_driver.label);
                device_desc.bcdDevice =
@@ -332,7 +355,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
        if (status < 0)
                goto fail;
 
-       INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+       dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+                       DRIVER_DESC);
 
        return 0;
 
index a2b5c092bda039bdf0c1cd70b7d4bc2d6445cc99..4ae579948e54dc67288499cea56929b220e98ebe 100644 (file)
@@ -83,7 +83,7 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f)
 }
 
 /* peak (theoretical) bulk transfer rate in bits-per-second */
-static inline unsigned bitrate(struct usb_gadget *g)
+static inline unsigned ecm_bitrate(struct usb_gadget *g)
 {
        if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
                return 13 * 512 * 8 * 1000 * 8;
@@ -107,7 +107,7 @@ static inline unsigned bitrate(struct usb_gadget *g)
  */
 
 #define LOG2_STATUS_INTERVAL_MSEC      5       /* 1 << 5 == 32 msec */
-#define STATUS_BYTECOUNT               16      /* 8 byte header + data */
+#define ECM_STATUS_BYTECOUNT           16      /* 8 byte header + data */
 
 
 /* interface descriptor: */
@@ -125,8 +125,8 @@ static struct usb_interface_descriptor ecm_control_intf __initdata = {
        /* .iInterface = DYNAMIC */
 };
 
-static struct usb_cdc_header_desc header_desc __initdata = {
-       .bLength =              sizeof header_desc,
+static struct usb_cdc_header_desc ecm_header_desc __initdata = {
+       .bLength =              sizeof ecm_header_desc,
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
 
@@ -141,8 +141,8 @@ static struct usb_cdc_union_desc ecm_union_desc __initdata = {
        /* .bSlaveInterface0 =  DYNAMIC */
 };
 
-static struct usb_cdc_ether_desc ether_desc __initdata = {
-       .bLength =              sizeof ether_desc,
+static struct usb_cdc_ether_desc ecm_desc __initdata = {
+       .bLength =              sizeof ecm_desc,
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
 
@@ -186,17 +186,17 @@ static struct usb_interface_descriptor ecm_data_intf __initdata = {
 
 /* full speed support: */
 
-static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .wMaxPacketSize =       __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
        .bInterval =            1 << LOG2_STATUS_INTERVAL_MSEC,
 };
 
-static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -204,7 +204,7 @@ static struct usb_endpoint_descriptor fs_in_desc __initdata = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -212,34 +212,34 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_descriptor_header *eth_fs_function[] __initdata = {
+static struct usb_descriptor_header *ecm_fs_function[] __initdata = {
        /* CDC ECM control descriptors */
        (struct usb_descriptor_header *) &ecm_control_intf,
-       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &ecm_header_desc,
        (struct usb_descriptor_header *) &ecm_union_desc,
-       (struct usb_descriptor_header *) &ether_desc,
+       (struct usb_descriptor_header *) &ecm_desc,
        /* NOTE: status endpoint might need to be removed */
-       (struct usb_descriptor_header *) &fs_notify_desc,
+       (struct usb_descriptor_header *) &fs_ecm_notify_desc,
        /* data interface, altsettings 0 and 1 */
        (struct usb_descriptor_header *) &ecm_data_nop_intf,
        (struct usb_descriptor_header *) &ecm_data_intf,
-       (struct usb_descriptor_header *) &fs_in_desc,
-       (struct usb_descriptor_header *) &fs_out_desc,
+       (struct usb_descriptor_header *) &fs_ecm_in_desc,
+       (struct usb_descriptor_header *) &fs_ecm_out_desc,
        NULL,
 };
 
 /* high speed support: */
 
-static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .wMaxPacketSize =       __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
        .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
 };
-static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
        .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -257,19 +257,19 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
        .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static struct usb_descriptor_header *eth_hs_function[] __initdata = {
+static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
        /* CDC ECM control descriptors */
        (struct usb_descriptor_header *) &ecm_control_intf,
-       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &ecm_header_desc,
        (struct usb_descriptor_header *) &ecm_union_desc,
-       (struct usb_descriptor_header *) &ether_desc,
+       (struct usb_descriptor_header *) &ecm_desc,
        /* NOTE: status endpoint might need to be removed */
-       (struct usb_descriptor_header *) &hs_notify_desc,
+       (struct usb_descriptor_header *) &hs_ecm_notify_desc,
        /* data interface, altsettings 0 and 1 */
        (struct usb_descriptor_header *) &ecm_data_nop_intf,
        (struct usb_descriptor_header *) &ecm_data_intf,
-       (struct usb_descriptor_header *) &hs_in_desc,
-       (struct usb_descriptor_header *) &hs_out_desc,
+       (struct usb_descriptor_header *) &hs_ecm_in_desc,
+       (struct usb_descriptor_header *) &hs_ecm_out_desc,
        NULL,
 };
 
@@ -329,14 +329,14 @@ static void ecm_do_notify(struct f_ecm *ecm)
                event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
                event->wValue = cpu_to_le16(0);
                event->wLength = cpu_to_le16(8);
-               req->length = STATUS_BYTECOUNT;
+               req->length = ECM_STATUS_BYTECOUNT;
 
                /* SPEED_CHANGE data is up/down speeds in bits/sec */
                data = req->buf + sizeof *event;
-               data[0] = cpu_to_le32(bitrate(cdev->gadget));
+               data[0] = cpu_to_le32(ecm_bitrate(cdev->gadget));
                data[1] = data[0];
 
-               DBG(cdev, "notify speed %d\n", bitrate(cdev->gadget));
+               DBG(cdev, "notify speed %d\n", ecm_bitrate(cdev->gadget));
                ecm->notify_state = ECM_NOTIFY_NONE;
                break;
        }
@@ -628,13 +628,13 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
        status = -ENODEV;
 
        /* allocate instance-specific endpoints */
-       ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc);
        if (!ep)
                goto fail;
        ecm->port.in_ep = ep;
        ep->driver_data = cdev; /* claim */
 
-       ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
        if (!ep)
                goto fail;
        ecm->port.out_ep = ep;
@@ -644,7 +644,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
         * don't treat it that way.  It's simpler, and some newer CDC
         * profiles (wireless handsets) no longer treat it as optional.
         */
-       ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc);
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc);
        if (!ep)
                goto fail;
        ecm->notify = ep;
@@ -656,47 +656,47 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
        ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
        if (!ecm->notify_req)
                goto fail;
-       ecm->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL);
+       ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL);
        if (!ecm->notify_req->buf)
                goto fail;
        ecm->notify_req->context = ecm;
        ecm->notify_req->complete = ecm_notify_complete;
 
        /* copy descriptors, and track endpoint copies */
-       f->descriptors = usb_copy_descriptors(eth_fs_function);
+       f->descriptors = usb_copy_descriptors(ecm_fs_function);
        if (!f->descriptors)
                goto fail;
 
-       ecm->fs.in = usb_find_endpoint(eth_fs_function,
-                       f->descriptors, &fs_in_desc);
-       ecm->fs.out = usb_find_endpoint(eth_fs_function,
-                       f->descriptors, &fs_out_desc);
-       ecm->fs.notify = usb_find_endpoint(eth_fs_function,
-                       f->descriptors, &fs_notify_desc);
+       ecm->fs.in = usb_find_endpoint(ecm_fs_function,
+                       f->descriptors, &fs_ecm_in_desc);
+       ecm->fs.out = usb_find_endpoint(ecm_fs_function,
+                       f->descriptors, &fs_ecm_out_desc);
+       ecm->fs.notify = usb_find_endpoint(ecm_fs_function,
+                       f->descriptors, &fs_ecm_notify_desc);
 
        /* support all relevant hardware speeds... we expect that when
         * hardware is dual speed, all bulk-capable endpoints work at
         * both speeds
         */
        if (gadget_is_dualspeed(c->cdev->gadget)) {
-               hs_in_desc.bEndpointAddress =
-                               fs_in_desc.bEndpointAddress;
-               hs_out_desc.bEndpointAddress =
-                               fs_out_desc.bEndpointAddress;
-               hs_notify_desc.bEndpointAddress =
-                               fs_notify_desc.bEndpointAddress;
+               hs_ecm_in_desc.bEndpointAddress =
+                               fs_ecm_in_desc.bEndpointAddress;
+               hs_ecm_out_desc.bEndpointAddress =
+                               fs_ecm_out_desc.bEndpointAddress;
+               hs_ecm_notify_desc.bEndpointAddress =
+                               fs_ecm_notify_desc.bEndpointAddress;
 
                /* copy descriptors, and track endpoint copies */
-               f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
+               f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
                if (!f->hs_descriptors)
                        goto fail;
 
-               ecm->hs.in = usb_find_endpoint(eth_hs_function,
-                               f->hs_descriptors, &hs_in_desc);
-               ecm->hs.out = usb_find_endpoint(eth_hs_function,
-                               f->hs_descriptors, &hs_out_desc);
-               ecm->hs.notify = usb_find_endpoint(eth_hs_function,
-                               f->hs_descriptors, &hs_notify_desc);
+               ecm->hs.in = usb_find_endpoint(ecm_hs_function,
+                               f->hs_descriptors, &hs_ecm_in_desc);
+               ecm->hs.out = usb_find_endpoint(ecm_hs_function,
+                               f->hs_descriptors, &hs_ecm_out_desc);
+               ecm->hs.notify = usb_find_endpoint(ecm_hs_function,
+                               f->hs_descriptors, &hs_ecm_notify_desc);
        }
 
        /* NOTE:  all that is done without knowing or caring about
@@ -795,7 +795,7 @@ int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
                if (status < 0)
                        return status;
                ecm_string_defs[1].id = status;
-               ether_desc.iMACAddress = status;
+               ecm_desc.iMACAddress = status;
        }
 
        /* allocate and initialize one new instance */
index eda4cde72c824c1aac2de550cfe24e7ae2ca5929..87dde012dacc8d251e25fc1d23eb73eeb1cf684a 100644 (file)
@@ -70,7 +70,7 @@ static struct usb_interface_descriptor loopback_intf = {
 
 /* full speed support: */
 
-static struct usb_endpoint_descriptor fs_source_desc = {
+static struct usb_endpoint_descriptor fs_loop_source_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -78,7 +78,7 @@ static struct usb_endpoint_descriptor fs_source_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_endpoint_descriptor fs_sink_desc = {
+static struct usb_endpoint_descriptor fs_loop_sink_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -88,14 +88,14 @@ static struct usb_endpoint_descriptor fs_sink_desc = {
 
 static struct usb_descriptor_header *fs_loopback_descs[] = {
        (struct usb_descriptor_header *) &loopback_intf,
-       (struct usb_descriptor_header *) &fs_sink_desc,
-       (struct usb_descriptor_header *) &fs_source_desc,
+       (struct usb_descriptor_header *) &fs_loop_sink_desc,
+       (struct usb_descriptor_header *) &fs_loop_source_desc,
        NULL,
 };
 
 /* high speed support: */
 
-static struct usb_endpoint_descriptor hs_source_desc = {
+static struct usb_endpoint_descriptor hs_loop_source_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -103,7 +103,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
        .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static struct usb_endpoint_descriptor hs_sink_desc = {
+static struct usb_endpoint_descriptor hs_loop_sink_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -113,8 +113,8 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
 
 static struct usb_descriptor_header *hs_loopback_descs[] = {
        (struct usb_descriptor_header *) &loopback_intf,
-       (struct usb_descriptor_header *) &hs_source_desc,
-       (struct usb_descriptor_header *) &hs_sink_desc,
+       (struct usb_descriptor_header *) &hs_loop_source_desc,
+       (struct usb_descriptor_header *) &hs_loop_sink_desc,
        NULL,
 };
 
@@ -152,7 +152,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f)
 
        /* allocate endpoints */
 
-       loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
+       loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc);
        if (!loop->in_ep) {
 autoconf_fail:
                ERROR(cdev, "%s: can't autoconfigure on %s\n",
@@ -161,17 +161,17 @@ autoconf_fail:
        }
        loop->in_ep->driver_data = cdev;        /* claim */
 
-       loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
+       loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
        if (!loop->out_ep)
                goto autoconf_fail;
        loop->out_ep->driver_data = cdev;       /* claim */
 
        /* support high speed hardware */
        if (gadget_is_dualspeed(c->cdev->gadget)) {
-               hs_source_desc.bEndpointAddress =
-                               fs_source_desc.bEndpointAddress;
-               hs_sink_desc.bEndpointAddress =
-                               fs_sink_desc.bEndpointAddress;
+               hs_loop_source_desc.bEndpointAddress =
+                               fs_loop_source_desc.bEndpointAddress;
+               hs_loop_sink_desc.bEndpointAddress =
+                               fs_loop_sink_desc.bEndpointAddress;
                f->hs_descriptors = hs_loopback_descs;
        }
 
@@ -255,8 +255,10 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
        struct usb_request                      *req;
        unsigned                                i;
 
-       src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
-       sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+       src = ep_choose(cdev->gadget,
+                       &hs_loop_source_desc, &fs_loop_source_desc);
+       sink = ep_choose(cdev->gadget,
+                       &hs_loop_sink_desc, &fs_loop_sink_desc);
 
        /* one endpoint writes data back IN to the host */
        ep = loop->in_ep;
index acb8d233aa1d24a02a5acc855a040755b809013b..fe1832875771539ec72d0fa693968a548a26fd79 100644 (file)
@@ -103,8 +103,8 @@ static struct usb_interface_descriptor subset_data_intf __initdata = {
        /* .iInterface = DYNAMIC */
 };
 
-static struct usb_cdc_header_desc header_desc __initdata = {
-       .bLength =              sizeof header_desc,
+static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
+       .bLength =              sizeof mdlm_header_desc,
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
 
@@ -152,7 +152,7 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
 
 /* full speed support: */
 
-static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -160,7 +160,7 @@ static struct usb_endpoint_descriptor fs_in_desc __initdata = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -170,18 +170,18 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = {
 
 static struct usb_descriptor_header *fs_eth_function[] __initdata = {
        (struct usb_descriptor_header *) &subset_data_intf,
-       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &mdlm_header_desc,
        (struct usb_descriptor_header *) &mdlm_desc,
        (struct usb_descriptor_header *) &mdlm_detail_desc,
        (struct usb_descriptor_header *) &ether_desc,
-       (struct usb_descriptor_header *) &fs_in_desc,
-       (struct usb_descriptor_header *) &fs_out_desc,
+       (struct usb_descriptor_header *) &fs_subset_in_desc,
+       (struct usb_descriptor_header *) &fs_subset_out_desc,
        NULL,
 };
 
 /* high speed support: */
 
-static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -189,7 +189,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
        .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -199,12 +199,12 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
 
 static struct usb_descriptor_header *hs_eth_function[] __initdata = {
        (struct usb_descriptor_header *) &subset_data_intf,
-       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &mdlm_header_desc,
        (struct usb_descriptor_header *) &mdlm_desc,
        (struct usb_descriptor_header *) &mdlm_detail_desc,
        (struct usb_descriptor_header *) &ether_desc,
-       (struct usb_descriptor_header *) &hs_in_desc,
-       (struct usb_descriptor_header *) &hs_out_desc,
+       (struct usb_descriptor_header *) &hs_subset_in_desc,
+       (struct usb_descriptor_header *) &hs_subset_out_desc,
        NULL,
 };
 
@@ -281,13 +281,13 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
        status = -ENODEV;
 
        /* allocate instance-specific endpoints */
-       ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_in_desc);
        if (!ep)
                goto fail;
        geth->port.in_ep = ep;
        ep->driver_data = cdev; /* claim */
 
-       ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
        if (!ep)
                goto fail;
        geth->port.out_ep = ep;
@@ -297,9 +297,9 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
        f->descriptors = usb_copy_descriptors(fs_eth_function);
 
        geth->fs.in = usb_find_endpoint(fs_eth_function,
-                       f->descriptors, &fs_in_desc);
+                       f->descriptors, &fs_subset_in_desc);
        geth->fs.out = usb_find_endpoint(fs_eth_function,
-                       f->descriptors, &fs_out_desc);
+                       f->descriptors, &fs_subset_out_desc);
 
 
        /* support all relevant hardware speeds... we expect that when
@@ -307,18 +307,18 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
         * both speeds
         */
        if (gadget_is_dualspeed(c->cdev->gadget)) {
-               hs_in_desc.bEndpointAddress =
-                               fs_in_desc.bEndpointAddress;
-               hs_out_desc.bEndpointAddress =
-                               fs_out_desc.bEndpointAddress;
+               hs_subset_in_desc.bEndpointAddress =
+                               fs_subset_in_desc.bEndpointAddress;
+               hs_subset_out_desc.bEndpointAddress =
+                               fs_subset_out_desc.bEndpointAddress;
 
                /* copy descriptors, and track endpoint copies */
                f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
 
                geth->hs.in = usb_find_endpoint(hs_eth_function,
-                               f->hs_descriptors, &hs_in_desc);
+                               f->hs_descriptors, &hs_subset_in_desc);
                geth->hs.out = usb_find_endpoint(hs_eth_function,
-                               f->hs_descriptors, &hs_out_desc);
+                               f->hs_descriptors, &hs_subset_out_desc);
        }
 
        /* NOTE:  all that is done without knowing or caring about
index ea2c31d18080d2a23025979a4c798f5133ceba48..0c632d22a6315a116beb9bb28a06b0d273322478 100644 (file)
 #include "gadget_chips.h"
 
 
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
 /*-------------------------------------------------------------------------*/
 
 #define DRIVER_DESC            "File-backed Storage Gadget"
index ea8651e3da1a53a205ffe67e88889b87d5073a89..6eee760410d6c052492cc854ea11cbc1ac840ffa 100644 (file)
 
 #include "gadget_chips.h"
 
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+/*-------------------------------------------------------------------------*/
+
+
 MODULE_AUTHOR("Ben Williamson");
 MODULE_LICENSE("GPL v2");
 
index e0090085b78ee74824ff2a3940a419a129e9570b..2b3b9e1dd2ee2987c3ee1420802a7544af2597f9 100644 (file)
 
 #include "gadget_chips.h"
 
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+/*-------------------------------------------------------------------------*/
+
 #define DRIVER_DESC            "Printer Gadget"
 #define DRIVER_VERSION         "2007 OCT 06"
 
@@ -1360,8 +1374,8 @@ printer_bind(struct usb_gadget *gadget)
 
 
        /* Setup the sysfs files for the printer gadget. */
-       dev->pdev = device_create_drvdata(usb_gadget_class, NULL,
-                                         g_printer_devno, NULL, "g_printer");
+       dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
+                                 NULL, "g_printer");
        if (IS_ERR(dev->pdev)) {
                ERROR(dev, "Failed to create device: g_printer\n");
                goto fail;
index 7228e856223626dab7e568eb0f1252391758a95b..8c26f5ea2b839070fe2afb6d8a41c66a36aeaafa 100644 (file)
@@ -57,11 +57,6 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
 #define rndis_debug            0
 #endif
 
-#define DBG(str,args...) do { \
-       if (rndis_debug) \
-               pr_debug(str , ## args); \
-       } while (0)
-
 #define RNDIS_MAX_CONFIGS      1
 
 
@@ -183,9 +178,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        if (!resp) return -ENOMEM;
 
        if (buf_len && rndis_debug > 1) {
-               DBG("query OID %08x value, len %d:\n", OID, buf_len);
+               pr_debug("query OID %08x value, len %d:\n", OID, buf_len);
                for (i = 0; i < buf_len; i += 16) {
-                       DBG("%03d: %08x %08x %08x %08x\n", i,
+                       pr_debug("%03d: %08x %08x %08x %08x\n", i,
                                get_unaligned_le32(&buf[i]),
                                get_unaligned_le32(&buf[i + 4]),
                                get_unaligned_le32(&buf[i + 8]),
@@ -209,7 +204,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_SUPPORTED_LIST:
-               DBG("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
+               pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
                length = sizeof (oid_supported_list);
                count  = length / sizeof (u32);
                for (i = 0; i < count; i++)
@@ -219,7 +214,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_HARDWARE_STATUS:
-               DBG("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
+               pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
                /* Bogus question!
                 * Hardware must be ready to receive high level protocols.
                 * BTW:
@@ -232,14 +227,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_MEDIA_SUPPORTED:
-               DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
+               pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
                *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
                retval = 0;
                break;
 
        /* mandatory */
        case OID_GEN_MEDIA_IN_USE:
-               DBG("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
+               pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
                /* one medium, one transport... (maybe you do it better) */
                *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
                retval = 0;
@@ -247,7 +242,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_MAXIMUM_FRAME_SIZE:
-               DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
+               pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
                if (rndis_per_dev_params [configNr].dev) {
                        *outbuf = cpu_to_le32 (
                                rndis_per_dev_params [configNr].dev->mtu);
@@ -258,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_LINK_SPEED:
                if (rndis_debug > 1)
-                       DBG("%s: OID_GEN_LINK_SPEED\n", __func__);
+                       pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
                if (rndis_per_dev_params [configNr].media_state
                                == NDIS_MEDIA_STATE_DISCONNECTED)
                        *outbuf = __constant_cpu_to_le32 (0);
@@ -270,7 +265,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_TRANSMIT_BLOCK_SIZE:
-               DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
+               pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
                if (rndis_per_dev_params [configNr].dev) {
                        *outbuf = cpu_to_le32 (
                                rndis_per_dev_params [configNr].dev->mtu);
@@ -280,7 +275,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_RECEIVE_BLOCK_SIZE:
-               DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
+               pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
                if (rndis_per_dev_params [configNr].dev) {
                        *outbuf = cpu_to_le32 (
                                rndis_per_dev_params [configNr].dev->mtu);
@@ -290,7 +285,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_VENDOR_ID:
-               DBG("%s: OID_GEN_VENDOR_ID\n", __func__);
+               pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__);
                *outbuf = cpu_to_le32 (
                        rndis_per_dev_params [configNr].vendorID);
                retval = 0;
@@ -298,7 +293,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_VENDOR_DESCRIPTION:
-               DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
+               pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
                length = strlen (rndis_per_dev_params [configNr].vendorDescr);
                memcpy (outbuf,
                        rndis_per_dev_params [configNr].vendorDescr, length);
@@ -306,7 +301,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                break;
 
        case OID_GEN_VENDOR_DRIVER_VERSION:
-               DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
+               pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
                /* Created as LE */
                *outbuf = rndis_driver_version;
                retval = 0;
@@ -314,14 +309,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_CURRENT_PACKET_FILTER:
-               DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
+               pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
                *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
                retval = 0;
                break;
 
        /* mandatory */
        case OID_GEN_MAXIMUM_TOTAL_SIZE:
-               DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
+               pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
                *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
                retval = 0;
                break;
@@ -329,14 +324,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_MEDIA_CONNECT_STATUS:
                if (rndis_debug > 1)
-                       DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
+                       pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
                *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
                                                .media_state);
                retval = 0;
                break;
 
        case OID_GEN_PHYSICAL_MEDIUM:
-               DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
+               pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
@@ -346,7 +341,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
         * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
         */
        case OID_GEN_MAC_OPTIONS:               /* from WinME */
-               DBG("%s: OID_GEN_MAC_OPTIONS\n", __func__);
+               pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
                *outbuf = __constant_cpu_to_le32(
                          NDIS_MAC_OPTION_RECEIVE_SERIALIZED
                        | NDIS_MAC_OPTION_FULL_DUPLEX);
@@ -358,7 +353,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_XMIT_OK:
                if (rndis_debug > 1)
-                       DBG("%s: OID_GEN_XMIT_OK\n", __func__);
+                       pr_debug("%s: OID_GEN_XMIT_OK\n", __func__);
                if (stats) {
                        *outbuf = cpu_to_le32(stats->tx_packets
                                - stats->tx_errors - stats->tx_dropped);
@@ -369,7 +364,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_RCV_OK:
                if (rndis_debug > 1)
-                       DBG("%s: OID_GEN_RCV_OK\n", __func__);
+                       pr_debug("%s: OID_GEN_RCV_OK\n", __func__);
                if (stats) {
                        *outbuf = cpu_to_le32(stats->rx_packets
                                - stats->rx_errors - stats->rx_dropped);
@@ -380,7 +375,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_XMIT_ERROR:
                if (rndis_debug > 1)
-                       DBG("%s: OID_GEN_XMIT_ERROR\n", __func__);
+                       pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__);
                if (stats) {
                        *outbuf = cpu_to_le32(stats->tx_errors);
                        retval = 0;
@@ -390,7 +385,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_RCV_ERROR:
                if (rndis_debug > 1)
-                       DBG("%s: OID_GEN_RCV_ERROR\n", __func__);
+                       pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__);
                if (stats) {
                        *outbuf = cpu_to_le32(stats->rx_errors);
                        retval = 0;
@@ -399,7 +394,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_GEN_RCV_NO_BUFFER:
-               DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
+               pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
                if (stats) {
                        *outbuf = cpu_to_le32(stats->rx_dropped);
                        retval = 0;
@@ -410,7 +405,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_PERMANENT_ADDRESS:
-               DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
+               pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = ETH_ALEN;
                        memcpy (outbuf,
@@ -422,7 +417,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_CURRENT_ADDRESS:
-               DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
+               pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
                if (rndis_per_dev_params [configNr].dev) {
                        length = ETH_ALEN;
                        memcpy (outbuf,
@@ -434,7 +429,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_MULTICAST_LIST:
-               DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
+               pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
                /* Multicast base address only */
                *outbuf = __constant_cpu_to_le32 (0xE0000000);
                retval = 0;
@@ -442,21 +437,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_MAXIMUM_LIST_SIZE:
-               DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
+               pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
                /* Multicast base address only */
                *outbuf = __constant_cpu_to_le32 (1);
                retval = 0;
                break;
 
        case OID_802_3_MAC_OPTIONS:
-               DBG("%s: OID_802_3_MAC_OPTIONS\n", __func__);
+               pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
                break;
 
        /* ieee802.3 statistics OIDs (table 4-4) */
 
        /* mandatory */
        case OID_802_3_RCV_ERROR_ALIGNMENT:
-               DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
+               pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
                if (stats) {
                        *outbuf = cpu_to_le32(stats->rx_frame_errors);
                        retval = 0;
@@ -465,14 +460,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        /* mandatory */
        case OID_802_3_XMIT_ONE_COLLISION:
-               DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
+               pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
 
        /* mandatory */
        case OID_802_3_XMIT_MORE_COLLISIONS:
-               DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
+               pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
                *outbuf = __constant_cpu_to_le32 (0);
                retval = 0;
                break;
@@ -504,9 +499,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                return -ENOMEM;
 
        if (buf_len && rndis_debug > 1) {
-               DBG("set OID %08x value, len %d:\n", OID, buf_len);
+               pr_debug("set OID %08x value, len %d:\n", OID, buf_len);
                for (i = 0; i < buf_len; i += 16) {
-                       DBG("%03d: %08x %08x %08x %08x\n", i,
+                       pr_debug("%03d: %08x %08x %08x %08x\n", i,
                                get_unaligned_le32(&buf[i]),
                                get_unaligned_le32(&buf[i + 4]),
                                get_unaligned_le32(&buf[i + 8]),
@@ -525,7 +520,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                 *      MULTICAST, ALL_MULTICAST, BROADCAST
                 */
                *params->filter = (u16)get_unaligned_le32(buf);
-               DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
+               pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
                        __func__, *params->filter);
 
                /* this call has a significant side effect:  it's
@@ -547,7 +542,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
 
        case OID_802_3_MULTICAST_LIST:
                /* I think we can ignore this */
-               DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
+               pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
                retval = 0;
                break;
 
@@ -606,7 +601,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
        rndis_resp_t            *r;
        struct rndis_params     *params = rndis_per_dev_params + configNr;
 
-       // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID));
+       /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */
        if (!params->dev)
                return -ENOTSUPP;
 
@@ -659,15 +654,15 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
        BufOffset = le32_to_cpu (buf->InformationBufferOffset);
 
 #ifdef VERBOSE_DEBUG
-       DBG("%s: Length: %d\n", __func__, BufLength);
-       DBG("%s: Offset: %d\n", __func__, BufOffset);
-       DBG("%s: InfoBuffer: ", __func__);
+       pr_debug("%s: Length: %d\n", __func__, BufLength);
+       pr_debug("%s: Offset: %d\n", __func__, BufOffset);
+       pr_debug("%s: InfoBuffer: ", __func__);
 
        for (i = 0; i < BufLength; i++) {
-               DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
+               pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
        }
 
-       DBG("\n");
+       pr_debug("\n");
 #endif
 
        resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
@@ -821,14 +816,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
        /* For USB: responses may take up to 10 seconds */
        switch (MsgType) {
        case REMOTE_NDIS_INITIALIZE_MSG:
-               DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
+               pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
                        __func__ );
                params->state = RNDIS_INITIALIZED;
                return  rndis_init_response (configNr,
                                        (rndis_init_msg_type *) buf);
 
        case REMOTE_NDIS_HALT_MSG:
-               DBG("%s: REMOTE_NDIS_HALT_MSG\n",
+               pr_debug("%s: REMOTE_NDIS_HALT_MSG\n",
                        __func__ );
                params->state = RNDIS_UNINITIALIZED;
                if (params->dev) {
@@ -846,7 +841,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                                        (rndis_set_msg_type *) buf);
 
        case REMOTE_NDIS_RESET_MSG:
-               DBG("%s: REMOTE_NDIS_RESET_MSG\n",
+               pr_debug("%s: REMOTE_NDIS_RESET_MSG\n",
                        __func__ );
                return rndis_reset_response (configNr,
                                        (rndis_reset_msg_type *) buf);
@@ -854,7 +849,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
        case REMOTE_NDIS_KEEPALIVE_MSG:
                /* For USB: host does this every 5 seconds */
                if (rndis_debug > 1)
-                       DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+                       pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
                                __func__ );
                return rndis_keepalive_response (configNr,
                                                 (rndis_keepalive_msg_type *)
@@ -870,7 +865,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
                {
                        unsigned i;
                        for (i = 0; i < MsgLength; i += 16) {
-                               DBG("%03d: "
+                               pr_debug("%03d: "
                                        " %02x %02x %02x %02x"
                                        " %02x %02x %02x %02x"
                                        " %02x %02x %02x %02x"
@@ -905,18 +900,18 @@ int rndis_register(void (*resp_avail)(void *v), void *v)
                        rndis_per_dev_params [i].used = 1;
                        rndis_per_dev_params [i].resp_avail = resp_avail;
                        rndis_per_dev_params [i].v = v;
-                       DBG("%s: configNr = %d\n", __func__, i);
+                       pr_debug("%s: configNr = %d\n", __func__, i);
                        return i;
                }
        }
-       DBG("failed\n");
+       pr_debug("failed\n");
 
        return -ENODEV;
 }
 
 void rndis_deregister (int configNr)
 {
-       DBG("%s: \n", __func__ );
+       pr_debug("%s: \n", __func__);
 
        if (configNr >= RNDIS_MAX_CONFIGS) return;
        rndis_per_dev_params [configNr].used = 0;
@@ -926,7 +921,7 @@ void rndis_deregister (int configNr)
 
 int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
 {
-       DBG("%s:\n", __func__ );
+       pr_debug("%s:\n", __func__);
        if (!dev)
                return -EINVAL;
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
@@ -939,7 +934,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
 
 int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
 {
-       DBG("%s:\n", __func__ );
+       pr_debug("%s:\n", __func__);
        if (!vendorDescr) return -1;
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 
@@ -951,7 +946,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
 
 int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
 {
-       DBG("%s: %u %u\n", __func__, medium, speed);
+       pr_debug("%s: %u %u\n", __func__, medium, speed);
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 
        rndis_per_dev_params [configNr].medium = medium;
@@ -1114,7 +1109,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
                        break;
                default:
                        if (fl_speed) p->speed = speed;
-                       else DBG("%c is not valid\n", c);
+                       else pr_debug("%c is not valid\n", c);
                        break;
                }
 
@@ -1159,12 +1154,12 @@ int __init rndis_init (void)
                                        &rndis_proc_fops,
                                        (void *)(rndis_per_dev_params + i))))
                {
-                       DBG("%s :remove entries", __func__);
+                       pr_debug("%s :remove entries", __func__);
                        while (i) {
                                sprintf (name, NAME_TEMPLATE, --i);
                                remove_proc_entry (name, NULL);
                        }
-                       DBG("\n");
+                       pr_debug("\n");
                        return -EIO;
                }
 #endif
index b3699afff002f4115b4c3ffaf1b975638aa88f1f..3faa7a7022df24926270d27399cfa92c69062b0e 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_acm.c"
+#include "f_serial.c"
+#include "u_serial.c"
+
+/*-------------------------------------------------------------------------*/
+
 /* Thanks to NetChip Technologies for donating this product ID.
 *
 * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
index 3791e6271903e7384a2a6773281d323c9de4b833..dbd575a194f3c895e46827a605d9e8984e388fb1 100644 (file)
@@ -52,7 +52,7 @@
  * this single "physical" link to be used by multiple virtual links.)
  */
 
-#define DRIVER_VERSION "29-May-2008"
+#define UETH__VERSION  "29-May-2008"
 
 struct eth_dev {
        /* lock is held while accessing port_usb
@@ -170,7 +170,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
        struct eth_dev  *dev = netdev_priv(net);
 
        strlcpy(p->driver, "g_ether", sizeof p->driver);
-       strlcpy(p->version, DRIVER_VERSION, sizeof p->version);
+       strlcpy(p->version, UETH__VERSION, sizeof p->version);
        strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
        strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
 }
index aa0bd4f126a1e5f7892e1ce645b187d88e4ea7f1..361d9659ac48726aa583d69accd2196edc3bd9df 100644 (file)
 #include "gadget_chips.h"
 
 
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_sourcesink.c"
+#include "f_loopback.c"
+
 /*-------------------------------------------------------------------------*/
 
 #define DRIVER_VERSION         "Cinco de Mayo 2008"
index 95b3ec89c126cdd0609306c034ae348a1324a184..52218562962481cdae48bff20594e845fb11ea5d 100644 (file)
@@ -344,7 +344,12 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
                goto err1;
        }
 
-       hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start);
+       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
+               retval = -ENOMEM;
+               goto err2;
+       }
 
        ohci = hcd_to_ohci(hcd);
        ohci_hcd_init(ohci);
@@ -355,11 +360,11 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                retval = -ENXIO;
-               goto err2;
+               goto err3;
        }
        retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
        if (retval)
-               goto err2;
+               goto err3;
 
        host_initialized = 1;
 
@@ -367,6 +372,8 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
                omap_ohci_clock_power(0);
 
        return 0;
+err3:
+       iounmap(hcd->regs);
 err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 err1:
@@ -401,6 +408,7 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
        }
        if (machine_is_omap_osk())
                omap_free_gpio(9);
+       iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
        clk_put(usb_dc_ck);
index db645936eedd3b5f8f5aff71a9eee85a12223757..1f0c2cf26e5d54532ad23a384c1ede813b625b3b 100644 (file)
@@ -123,14 +123,10 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
 
 static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
 {
-       if (!list_empty(&td->list)) {
-               dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
-               WARN_ON(1);
-       }
-       if (!list_empty(&td->fl_list)) {
-               dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
-               WARN_ON(1);
-       }
+       if (!list_empty(&td->list))
+               dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
+       if (!list_empty(&td->fl_list))
+               dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
 
        dma_pool_free(uhci->td_pool, td, td->dma_handle);
 }
@@ -295,10 +291,8 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
 static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
        WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
-       if (!list_empty(&qh->queue)) {
-               dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);
-               WARN_ON(1);
-       }
+       if (!list_empty(&qh->queue))
+               dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
 
        list_del(&qh->node);
        if (qh->udev) {
@@ -746,11 +740,9 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci,
 {
        struct uhci_td *td, *tmp;
 
-       if (!list_empty(&urbp->node)) {
-               dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
+       if (!list_empty(&urbp->node))
+               dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
                                urbp->urb);
-               WARN_ON(1);
-       }
 
        list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
                uhci_remove_td_from_urbp(td);
index 4cfa25b0f44e5620bc45b4447eee62737bf523f2..cc8e0a926f9991749be2cc48cce5a17a8bea9d79 100644 (file)
@@ -595,9 +595,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
         } while(value);
         kit->dev_no = bit;
 
-       kit->dev = device_create_drvdata(phidget_class, &kit->udev->dev,
-                                       MKDEV(0, 0), kit,
-                                       "interfacekit%d", kit->dev_no);
+       kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0),
+                                kit, "interfacekit%d", kit->dev_no);
         if (IS_ERR(kit->dev)) {
                 rc = PTR_ERR(kit->dev);
                 kit->dev = NULL;
index 9b4696f21b22849079b062336b7ef93aa1ed757e..38088b44349eb86695fc837fe54fc84ee1e2e482 100644 (file)
@@ -365,9 +365,8 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
        } while(value);
        mc->dev_no = bit;
 
-       mc->dev = device_create_drvdata(phidget_class, &mc->udev->dev,
-                                       MKDEV(0, 0), mc,
-                                       "motorcontrol%d", mc->dev_no);
+       mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc,
+                               "motorcontrol%d", mc->dev_no);
        if (IS_ERR(mc->dev)) {
                rc = PTR_ERR(mc->dev);
                mc->dev = NULL;
index 1ca7ddb41d4dfe0014381391766bf8898947aa69..bef6fe16364b47c77c03ddc580744fa310a6daa5 100644 (file)
@@ -275,9 +275,8 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
         } while (value);
        dev->dev_no = bit;
 
-       dev->dev = device_create_drvdata(phidget_class, &dev->udev->dev,
-                                        MKDEV(0, 0), dev,
-                                        "servo%d", dev->dev_no);
+       dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0),
+                                dev, "servo%d", dev->dev_no);
        if (IS_ERR(dev->dev)) {
                rc = PTR_ERR(dev->dev);
                dev->dev = NULL;
index 6566fc0a322853a50b8f212d6b82df868da9b4d5..c9de3f027aab07a9907b331f25c7723ac012d8e3 100644 (file)
@@ -1162,9 +1162,9 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
        if (minor >= MON_BIN_MAX_MINOR)
                return 0;
 
-       dev = device_create_drvdata(mon_bin_class, ubus? ubus->controller: NULL,
-                                   MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
-                                   "usbmon%d", minor);
+       dev = device_create(mon_bin_class, ubus ? ubus->controller : NULL,
+                           MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
+                           "usbmon%d", minor);
        if (IS_ERR(dev))
                return 0;
 
index f79c2040758b4ab43d867acaa451c1d2b3891934..0f13448c6f799b05fdebd78e67031610ff25514e 100644 (file)
@@ -76,6 +76,14 @@ config FB_DDC
        select I2C
        default n
 
+config FB_BOOT_VESA_SUPPORT
+       bool
+       depends on FB
+       default n
+       ---help---
+         If true, at least one selected framebuffer driver can take advantage
+         of VESA video modes set at an early boot stage via the vga= parameter.
+
 config FB_CFB_FILLRECT
        tristate
        depends on FB
@@ -254,16 +262,24 @@ config FB_PM2
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        help
-         This is the frame buffer device driver for the Permedia2 AGP frame
-         buffer card from ASK, aka `Graphic Blaster Exxtreme'.  There is a
-         product page at
-         <http://www.ask.com.hk/product/Permedia%202/permedia2.htm>.
+         This is the frame buffer device driver for cards based on
+         the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
+         The driver was tested on the following cards:
+               Diamond FireGL 1000 PRO AGP
+               ELSA Gloria Synergy PCI
+               Appian Jeronimo PRO (both heads) PCI
+               3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
+               Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
+               ASK Graphic Blaster Exxtreme AGP
+
+         To compile this driver as a module, choose M here: the
+         module will be called pm2fb.
 
 config FB_PM2_FIFO_DISCONNECT
        bool "enable FIFO disconnect feature"
        depends on FB_PM2 && PCI
        help
-         Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2).
+         Support the Permedia2 FIFO disconnect feature.
 
 config FB_ARMCLCD
        tristate "ARM PrimeCell PL110 support"
@@ -673,6 +689,7 @@ config FB_VESA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
+       select FB_BOOT_VESA_SUPPORT
        help
          This is the frame buffer device driver for generic VESA 2.0
          compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -681,23 +698,14 @@ config FB_VESA
 
 config FB_EFI
        bool "EFI-based Framebuffer Support"
-       depends on (FB = y) && X86
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       help
-         This is the EFI frame buffer device driver. If the firmware on
-         your platform is UEFI2.0, select Y to add support for
-         Graphics Output Protocol for early console messages to appear.
-
-config FB_IMAC
-       bool "Intel-based Macintosh Framebuffer Support"
        depends on (FB = y) && X86 && EFI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        help
-         This is the frame buffer device driver for the Intel-based Macintosh
+         This is the EFI frame buffer device driver. If the firmware on
+         your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
+         using the EFI framebuffer as your console.
 
 config FB_N411
        tristate "N411 Apollo/Hecuba devkit support"
@@ -1118,6 +1126,7 @@ config FB_INTEL
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
+       select FB_BOOT_VESA_SUPPORT
        help
          This driver supports the on-board graphics built in to the Intel
           830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
@@ -1470,6 +1479,7 @@ config FB_SIS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
+       select FB_BOOT_VESA_SUPPORT
        help
          This is the frame buffer device driver for the SiS 300, 315, 330
          and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1492,6 +1502,24 @@ config FB_SIS_315
          (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
          as XGI V3XT, V5, V8 and Z7.
 
+config FB_VIA
+       tristate "VIA UniChrome (Pro) and Chrome9 display support"
+       depends on FB && PCI
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       select FB_SOFT_CURSOR
+       select I2C_ALGOBIT
+       select I2C
+       help
+         This is the frame buffer device driver for Graphics chips of VIA
+         UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
+         CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
+         /P4M900,VX800)
+         Say Y if you have a VIA UniChrome graphics board.
+
+         To compile this driver as a module, choose M here: the
+         module will be called viafb.
 config FB_NEOMAGIC
        tristate "NeoMagic display support"
        depends on FB && PCI
@@ -1521,25 +1549,25 @@ config FB_KYRO
          module will be called kyrofb.
 
 config FB_3DFX
-       tristate "3Dfx Banshee/Voodoo3 display support"
+       tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
        depends on FB && PCI
        select FB_CFB_IMAGEBLIT
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        help
-         This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
-         chips. Say Y if you have such a graphics board.
+         This driver supports graphics boards with the 3Dfx Banshee,
+         Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
+         such a graphics board.
 
          To compile this driver as a module, choose M here: the
          module will be called tdfxfb.
 
 config FB_3DFX_ACCEL
-       bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)"
+       bool "3Dfx Acceleration functions (EXPERIMENTAL)"
        depends on FB_3DFX && EXPERIMENTAL
        ---help---
-       This will compile the 3Dfx Banshee/Voodoo3 frame buffer device
-       with acceleration functions.
-
+       This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
+       device driver with acceleration functions.
 
 config FB_VOODOO1
        tristate "3Dfx Voodoo Graphics (sst1) support"
@@ -1604,17 +1632,16 @@ config FB_TRIDENT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        ---help---
-         This driver is supposed to support graphics boards with the
-         Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
+         This is the frame buffer device driver for Trident PCI/AGP chipsets.
+         Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
+         and Blade XP.
+         There are also integrated versions of these chips called CyberXXXX,
+         CyberImage or CyberBlade. These chips are mostly found in laptops
          but also on some motherboards. For more information, read
          <file:Documentation/fb/tridentfb.txt>
 
-         Cyberblade/i1 support will be removed soon, use the cyblafb driver
-         instead.
-
          Say Y if you have such a graphics board.
 
-
          To compile this driver as a module, choose M here: the
          module will be called tridentfb.
 
@@ -1869,6 +1896,28 @@ config FB_SH_MOBILE_LCDC
        ---help---
          Frame buffer driver for the on-chip SH-Mobile LCD controller.
 
+config FB_TMIO
+       tristate "Toshiba Mobile IO FrameBuffer support"
+       depends on FB && MFD_CORE
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       ---help---
+         Frame buffer driver for the Toshiba Mobile IO integrated as found
+         on the Sharp SL-6000 series
+
+         This driver is also available as a module ( = code which can be
+         inserted and removed from the running kernel whenever you want). The
+         module will be called tmiofb. If you want to compile it as a module,
+         say M here and read <file:Documentation/kbuild/modules.txt>.
+
+         If unsure, say N.
+
+config FB_TMIO_ACCELL
+       bool "tmiofb acceleration"
+       depends on FB_TMIO
+       default y
+
 config FB_S3C2410
        tristate "S3C2410 LCD framebuffer support"
        depends on FB && ARCH_S3C2410
index ad0330bf9be3a7fe6d26aa82869be16dae41856c..248bddc8d0b0bb0e7e970d30dc2427f51b6d6e76 100644 (file)
@@ -42,6 +42,7 @@ obj-$(CONFIG_FB_ATY)            += aty/ macmodes.o
 obj-$(CONFIG_FB_ATY128)                  += aty/ macmodes.o
 obj-$(CONFIG_FB_RADEON)                  += aty/
 obj-$(CONFIG_FB_SIS)             += sis/
+obj-$(CONFIG_FB_VIA)             += via/
 obj-$(CONFIG_FB_KYRO)             += kyro/
 obj-$(CONFIG_FB_SAVAGE)                  += savage/
 obj-$(CONFIG_FB_GEODE)           += geode/
@@ -97,6 +98,7 @@ obj-$(CONFIG_FB_CIRRUS)                 += cirrusfb.o
 obj-$(CONFIG_FB_ASILIANT)        += asiliantfb.o
 obj-$(CONFIG_FB_PXA)             += pxafb.o
 obj-$(CONFIG_FB_W100)            += w100fb.o
+obj-$(CONFIG_FB_TMIO)            += tmiofb.o
 obj-$(CONFIG_FB_AU1100)                  += au1100fb.o
 obj-$(CONFIG_FB_AU1200)                  += au1200fb.o
 obj-$(CONFIG_FB_PMAG_AA)         += pmag-aa-fb.o
@@ -124,7 +126,6 @@ obj-$(CONFIG_FB_CARMINE)          += carminefb.o
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
 obj-$(CONFIG_FB_VESA)             += vesafb.o
-obj-$(CONFIG_FB_IMAC)             += imacfb.o
 obj-$(CONFIG_FB_EFI)              += efifb.o
 obj-$(CONFIG_FB_VGA16)            += vga16fb.o
 obj-$(CONFIG_FB_OF)               += offb.o
index d38fd5217422f8de3e3b97ecbd5cbd65056a0977..f8d0a57a07cbe3852d4128b0b6d46c8eddefebd5 100644 (file)
@@ -372,6 +372,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
        var->transp.offset = var->transp.length = 0;
        var->xoffset = var->yoffset = 0;
 
+       if (info->fix.smem_len) {
+               unsigned int smem_len = (var->xres_virtual * var->yres_virtual
+                                        * ((var->bits_per_pixel + 7) / 8));
+               if (smem_len > info->fix.smem_len)
+                       return -EINVAL;
+       }
+
        /* Saturate vertical and horizontal timings at maximum values */
        var->vsync_len = min_t(u32, var->vsync_len,
                        (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1);
index aa95f835024282ca4e88142d9f957d393271c4ee..8718f7349d6b8961eb1ed90d3ce8ea13b75a5853 100644 (file)
@@ -5,61 +5,61 @@
  * --dte
  */
 
-static void radeon_fixup_offset(struct radeonfb_info *rinfo)
+#define FLUSH_CACHE_WORKAROUND 1
+
+void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries)
 {
-       u32 local_base;
-
-       /* *** Ugly workaround *** */
-       /*
-        * On some platforms, the video memory is mapped at 0 in radeon chip space
-        * (like PPCs) by the firmware. X will always move it up so that it's seen
-        * by the chip to be at the same address as the PCI BAR.
-        * That means that when switching back from X, there is a mismatch between
-        * the offsets programmed into the engine. This means that potentially,
-        * accel operations done before radeonfb has a chance to re-init the engine
-        * will have incorrect offsets, and potentially trash system memory !
-        *
-        * The correct fix is for fbcon to never call any accel op before the engine
-        * has properly been re-initialized (by a call to set_var), but this is a
-        * complex fix. This workaround in the meantime, called before every accel
-        * operation, makes sure the offsets are in sync.
-        */
+       int i;
 
-       radeon_fifo_wait (1);
-       local_base = INREG(MC_FB_LOCATION) << 16;
-       if (local_base == rinfo->fb_local_base)
-               return;
+       for (i=0; i<2000000; i++) {
+               rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f;
+               if (rinfo->fifo_free >= entries)
+                       return;
+               udelay(10);
+       }
+       printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
+       /* XXX Todo: attempt to reset the engine */
+}
 
-       rinfo->fb_local_base = local_base;
+static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
+{
+       if (entries <= rinfo->fifo_free)
+               rinfo->fifo_free -= entries;
+       else
+               radeon_fifo_update_and_wait(rinfo, entries);
+}
 
-       radeon_fifo_wait (3);
-       OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
-                                    (rinfo->fb_local_base >> 10));
-       OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
-       OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg,
+                                    u32 *cache, u32 new_val)
+{
+       if (new_val == *cache)
+               return;
+       *cache = new_val;
+       radeon_fifo_wait(rinfo, 1);
+       OUTREG(reg, new_val);
 }
 
 static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, 
                                   const struct fb_fillrect *region)
 {
-       radeon_fifo_wait(4);  
-  
-       OUTREG(DP_GUI_MASTER_CNTL,  
-               rinfo->dp_gui_master_cntl  /* contains, like GMC_DST_32BPP */
-                | GMC_BRUSH_SOLID_COLOR
-                | ROP3_P);
-       if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP)
-               OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]);
-       else
-               OUTREG(DP_BRUSH_FRGD_CLR, region->color);
-       OUTREG(DP_WRITE_MSK, 0xffffffff);
-       OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
-
-       radeon_fifo_wait(2);
+       radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
+                         rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P);
+       radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
+                         DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+       radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache,
+                         region->color);
+
+       /* Ensure the dst cache is flushed and the engine idle before
+        * issuing the operation.
+        *
+        * This works around engine lockups on some cards
+        */
+#if FLUSH_CACHE_WORKAROUND
+       radeon_fifo_wait(rinfo, 2);
        OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
        OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
-
-       radeon_fifo_wait(2);  
+#endif
+       radeon_fifo_wait(rinfo, 2);
        OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
        OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
 }
@@ -70,15 +70,14 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
        struct fb_fillrect modded;
        int vxres, vyres;
   
-       if (info->state != FBINFO_STATE_RUNNING)
+       WARN_ON(rinfo->gfx_mode);
+       if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
                return;
        if (info->flags & FBINFO_HWACCEL_DISABLED) {
                cfb_fillrect(info, region);
                return;
        }
 
-       radeon_fixup_offset(rinfo);
-
        vxres = info->var.xres_virtual;
        vyres = info->var.yres_virtual;
 
@@ -91,6 +90,10 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
        if(modded.dx + modded.width  > vxres) modded.width  = vxres - modded.dx;
        if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
 
+       if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+           info->fix.visual == FB_VISUAL_DIRECTCOLOR )
+               modded.color = ((u32 *) (info->pseudo_palette))[region->color];
+
        radeonfb_prim_fillrect(rinfo, &modded);
 }
 
@@ -109,22 +112,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
        if ( xdir < 0 ) { sx += w-1; dx += w-1; }
        if ( ydir < 0 ) { sy += h-1; dy += h-1; }
 
-       radeon_fifo_wait(3);
-       OUTREG(DP_GUI_MASTER_CNTL,
-               rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */
-               | GMC_BRUSH_NONE
-               | GMC_SRC_DSTCOLOR
-               | ROP3_S 
-               | DP_SRC_SOURCE_MEMORY );
-       OUTREG(DP_WRITE_MSK, 0xffffffff);
-       OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
-                       | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
-
-       radeon_fifo_wait(2);
+       radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
+                         rinfo->dp_gui_mc_base |
+                         GMC_BRUSH_NONE |
+                         GMC_SRC_DATATYPE_COLOR |
+                         ROP3_S |
+                         DP_SRC_SOURCE_MEMORY);
+       radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
+                         (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) |
+                         (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
+
+#if FLUSH_CACHE_WORKAROUND
+       radeon_fifo_wait(rinfo, 2);
        OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
        OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
-
-       radeon_fifo_wait(3);
+#endif
+       radeon_fifo_wait(rinfo, 3);
        OUTREG(SRC_Y_X, (sy << 16) | sx);
        OUTREG(DST_Y_X, (dy << 16) | dx);
        OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
@@ -143,15 +146,14 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        modded.width  = area->width;
        modded.height = area->height;
   
-       if (info->state != FBINFO_STATE_RUNNING)
+       WARN_ON(rinfo->gfx_mode);
+       if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
                return;
        if (info->flags & FBINFO_HWACCEL_DISABLED) {
                cfb_copyarea(info, area);
                return;
        }
 
-       radeon_fixup_offset(rinfo);
-
        vxres = info->var.xres_virtual;
        vyres = info->var.yres_virtual;
 
@@ -168,13 +170,112 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        radeonfb_prim_copyarea(rinfo, &modded);
 }
 
+static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
+                                   const struct fb_image *image,
+                                   u32 fg, u32 bg)
+{
+       unsigned int src_bytes, dwords;
+       u32 *bits;
+
+       radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
+                         rinfo->dp_gui_mc_base |
+                         GMC_BRUSH_NONE |
+                         GMC_SRC_DATATYPE_MONO_FG_BG |
+                         ROP3_S |
+                         GMC_BYTE_ORDER_MSB_TO_LSB |
+                         DP_SRC_SOURCE_HOST_DATA);
+       radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
+                         DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+       radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
+       radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
+
+       radeon_fifo_wait(rinfo, 1);
+       OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
+
+       /* Ensure the dst cache is flushed and the engine idle before
+        * issuing the operation.
+        *
+        * This works around engine lockups on some cards
+        */
+#if FLUSH_CACHE_WORKAROUND
+       radeon_fifo_wait(rinfo, 2);
+       OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
+       OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
+#endif
+
+       /* X here pads width to a multiple of 32 and uses the clipper to
+        * adjust the result. Is that really necessary ? Things seem to
+        * work ok for me without that and the doco doesn't seem to imply
+        * there is such a restriction.
+        */
+       OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height);
+
+       src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
+       dwords = (src_bytes + 3) / 4;
+       bits = (u32*)(image->data);
+
+       while(dwords >= 8) {
+               radeon_fifo_wait(rinfo, 8);
+#if BITS_PER_LONG == 64
+               __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0);
+               __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2);
+               __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4);
+               __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6);
+               bits += 8;
+#else
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7);
+#endif
+               dwords -= 8;
+       }
+       while(dwords--) {
+               radeon_fifo_wait(rinfo, 1);
+               __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
+       }
+}
+
 void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct radeonfb_info *rinfo = info->par;
+       u32 fg, bg;
 
-       if (info->state != FBINFO_STATE_RUNNING)
+       WARN_ON(rinfo->gfx_mode);
+       if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
+               return;
+
+       if (!image->width || !image->height)
                return;
-       radeon_engine_idle();
+
+       /* We only do 1 bpp color expansion for now */
+       if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
+               goto fallback;
+
+       /* Fallback if running out of the screen. We may do clipping
+        * in the future */
+       if ((image->dx + image->width) > info->var.xres_virtual ||
+           (image->dy + image->height) > info->var.yres_virtual)
+               goto fallback;
+
+       if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+           info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+               fg = ((u32*)(info->pseudo_palette))[image->fg_color];
+               bg = ((u32*)(info->pseudo_palette))[image->bg_color];
+       } else {
+               fg = image->fg_color;
+               bg = image->bg_color;
+       }
+
+       radeonfb_prim_imageblit(rinfo, image, fg, bg);
+       return;
+
+ fallback:
+       radeon_engine_idle(rinfo);
 
        cfb_imageblit(info, image);
 }
@@ -185,7 +286,8 @@ int radeonfb_sync(struct fb_info *info)
 
        if (info->state != FBINFO_STATE_RUNNING)
                return 0;
-       radeon_engine_idle();
+
+       radeon_engine_idle(rinfo);
 
        return 0;
 }
@@ -211,9 +313,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
        host_path_cntl = INREG(HOST_PATH_CNTL);
        rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
 
-       if (rinfo->family == CHIP_FAMILY_R300 ||
-           rinfo->family == CHIP_FAMILY_R350 ||
-           rinfo->family == CHIP_FAMILY_RV350) {
+       if (IS_R300_VARIANT(rinfo)) {
                u32 tmp;
 
                OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
@@ -249,9 +349,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
        INREG(HOST_PATH_CNTL);
        OUTREG(HOST_PATH_CNTL, host_path_cntl);
 
-       if (rinfo->family != CHIP_FAMILY_R300 &&
-           rinfo->family != CHIP_FAMILY_R350 &&
-           rinfo->family != CHIP_FAMILY_RV350)
+       if (!IS_R300_VARIANT(rinfo))
                OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
 
        OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -265,15 +363,24 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
        /* disable 3D engine */
        OUTREG(RB3D_CNTL, 0);
 
+       rinfo->fifo_free = 0;
        radeonfb_engine_reset(rinfo);
 
-       radeon_fifo_wait (1);
-       if ((rinfo->family != CHIP_FAMILY_R300) &&
-           (rinfo->family != CHIP_FAMILY_R350) &&
-           (rinfo->family != CHIP_FAMILY_RV350))
+       radeon_fifo_wait(rinfo, 1);
+       if (IS_R300_VARIANT(rinfo)) {
+               OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) |
+                      RB2D_DC_AUTOFLUSH_ENABLE |
+                      RB2D_DC_DC_DISABLE_IGNORE_PE);
+       } else {
+               /* This needs to be double checked with ATI. Latest X driver
+                * completely "forgets" to set this register on < r3xx, and
+                * we used to just write 0 there... I'll keep the 0 and update
+                * that when we have sorted things out on X side.
+                */
                OUTREG(RB2D_DSTCACHE_MODE, 0);
+       }
 
-       radeon_fifo_wait (3);
+       radeon_fifo_wait(rinfo, 3);
        /* We re-read MC_FB_LOCATION from card as it can have been
         * modified by XFree drivers (ouch !)
         */
@@ -284,41 +391,57 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
        OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
        OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
 
-       radeon_fifo_wait (1);
-#if defined(__BIG_ENDIAN)
+       radeon_fifo_wait(rinfo, 1);
+#ifdef __BIG_ENDIAN
        OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
 #else
        OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
 #endif
-       radeon_fifo_wait (2);
+       radeon_fifo_wait(rinfo, 2);
        OUTREG(DEFAULT_SC_TOP_LEFT, 0);
        OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
                                         DEFAULT_SC_BOTTOM_MAX));
 
+       /* set default DP_GUI_MASTER_CNTL */
        temp = radeon_get_dstbpp(rinfo->depth);
-       rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
+       rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
 
-       radeon_fifo_wait (1);
-       OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
-                                   GMC_BRUSH_SOLID_COLOR |
-                                   GMC_SRC_DATATYPE_COLOR));
+       rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base |
+               GMC_BRUSH_SOLID_COLOR |
+               GMC_SRC_DATATYPE_COLOR;
+       radeon_fifo_wait(rinfo, 1);
+       OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache);
 
-       radeon_fifo_wait (7);
 
        /* clear line drawing regs */
+       radeon_fifo_wait(rinfo, 2);
        OUTREG(DST_LINE_START, 0);
        OUTREG(DST_LINE_END, 0);
 
-       /* set brush color regs */
-       OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
-       OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
-
-       /* set source color regs */
-       OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
-       OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
+       /* set brush and source color regs */
+       rinfo->dp_brush_fg_cache = 0xffffffff;
+       rinfo->dp_brush_bg_cache = 0x00000000;
+       rinfo->dp_src_fg_cache = 0xffffffff;
+       rinfo->dp_src_bg_cache = 0x00000000;
+       radeon_fifo_wait(rinfo, 4);
+       OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache);
+       OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache);
+       OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache);
+       OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache);
+
+       /* Default direction */
+       rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM;
+       radeon_fifo_wait(rinfo, 1);
+       OUTREG(DP_CNTL, rinfo->dp_cntl_cache);
 
        /* default write mask */
+       radeon_fifo_wait(rinfo, 1);
        OUTREG(DP_WRITE_MSK, 0xffffffff);
 
-       radeon_engine_idle ();
+       /* Default to no swapping of host data */
+       radeon_fifo_wait(rinfo, 1);
+       OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE);
+
+       /* Make sure it's settled */
+       radeon_engine_idle(rinfo);
 }
index 1a056adb61c836784fce99d1c0314e710f4948e8..f343ba83f0ae0dbb6e50d25aa8ea95239598b1fd 100644 (file)
@@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd)
                level = bd->props.brightness;
 
        del_timer_sync(&rinfo->lvds_timer);
-       radeon_engine_idle();
+       radeon_engine_idle(rinfo);
 
        lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
        if (level > 0) {
index 652273e9f5f9223fc80261d035c114765ea59f71..9a5821c65ebf22fd2d492ee3972002bb2f5cc651 100644 (file)
@@ -852,7 +852,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
         if (rinfo->asleep)
                return 0;
 
-       radeon_fifo_wait(2);
         OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
                             * var->bits_per_pixel / 8) & ~7);
         return 0;
@@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
                        if (rc)
                                return rc;
 
-                       radeon_fifo_wait(2);
                        if (value & 0x01) {
                                tmp = INREG(LVDS_GEN_CNTL);
 
@@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
        if (rinfo->lock_blank)
                return 0;
 
-       radeon_engine_idle();
+       radeon_engine_idle(rinfo);
 
        val = INREG(CRTC_EXT_CNTL);
         val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
@@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info)
 
        if (rinfo->asleep)
                return 0;
-               
+
        return radeon_screen_blank(rinfo, blank, 0);
 }
 
@@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
         pindex = regno;
 
         if (!rinfo->asleep) {
-               radeon_fifo_wait(9);
-
                if (rinfo->bpp == 16) {
                        pindex = regno * 8;
 
@@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
 {
        int i;
 
-       radeon_fifo_wait(20);
-
        /* Workaround from XFree */
        if (rinfo->is_mobility) {
                /* A temporal workaround for the occational blanking on certain laptop
@@ -1286,11 +1280,10 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
        radeon_pll_errata_after_data(rinfo);
 
        /* Set PPLL ref. div */
-       if (rinfo->family == CHIP_FAMILY_R300 ||
+       if (IS_R300_VARIANT(rinfo) ||
            rinfo->family == CHIP_FAMILY_RS300 ||
-           rinfo->family == CHIP_FAMILY_R350 ||
-           rinfo->family == CHIP_FAMILY_RV350 ||
-           rinfo->family == CHIP_FAMILY_RV380 ) {
+           rinfo->family == CHIP_FAMILY_RS400 ||
+           rinfo->family == CHIP_FAMILY_RS480) {
                if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
                        /* When restoring console mode, use saved PPLL_REF_DIV
                         * setting.
@@ -1342,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data)
 {
        struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
 
-       radeon_engine_idle();
+       radeon_engine_idle(rinfo);
 
        OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
 }
@@ -1360,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
        if (nomodeset)
                return;
 
+       radeon_engine_idle(rinfo);
+
        if (!regs_only)
                radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
 
-       radeon_fifo_wait(31);
        for (i=0; i<10; i++)
                OUTREG(common_regs[i].reg, common_regs[i].val);
 
@@ -1391,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
        radeon_write_pll_regs(rinfo, mode);
 
        if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
-               radeon_fifo_wait(10);
                OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
                OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
                OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
@@ -1406,7 +1399,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
        if (!regs_only)
                radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
 
-       radeon_fifo_wait(2);
        OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
        
        return;
@@ -1461,10 +1453,7 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
                /* Not all chip revs have the same format for this register,
                 * extract the source selection
                 */
-               if (rinfo->family == CHIP_FAMILY_R200 ||
-                   rinfo->family == CHIP_FAMILY_R300 ||
-                   rinfo->family == CHIP_FAMILY_R350 ||
-                   rinfo->family == CHIP_FAMILY_RV350) {
+               if (rinfo->family == CHIP_FAMILY_R200 || IS_R300_VARIANT(rinfo)) {
                        source = (fp2_gen_cntl >> 10) & 0x3;
                        /* sourced from transform unit, check for transform unit
                         * own source
@@ -1560,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info)
        /* We always want engine to be idle on a mode switch, even
         * if we won't actually change the mode
         */
-       radeon_engine_idle();
+       radeon_engine_idle(rinfo);
 
        hSyncStart = mode->xres + mode->right_margin;
        hSyncEnd = hSyncStart + mode->hsync_len;
@@ -1855,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info)
        return 0;
 }
 
-
 static struct fb_ops radeonfb_ops = {
        .owner                  = THIS_MODULE,
        .fb_check_var           = radeonfb_check_var,
@@ -1879,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
        info->par = rinfo;
        info->pseudo_palette = rinfo->pseudo_palette;
        info->flags = FBINFO_DEFAULT
+                   | FBINFO_HWACCEL_IMAGEBLIT
                    | FBINFO_HWACCEL_COPYAREA
                    | FBINFO_HWACCEL_FILLRECT
                    | FBINFO_HWACCEL_XPAN
@@ -2005,11 +1994,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
             (rinfo->family == CHIP_FAMILY_RS200) ||
             (rinfo->family == CHIP_FAMILY_RS300) ||
             (rinfo->family == CHIP_FAMILY_RC410) ||
+            (rinfo->family == CHIP_FAMILY_RS400) ||
            (rinfo->family == CHIP_FAMILY_RS480) ) {
           u32 tom = INREG(NB_TOM);
           tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
 
-               radeon_fifo_wait(6);
           OUTREG(MC_FB_LOCATION, tom);
           OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
           OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
index 8c8fa35f1b7c2b13cd6a35341abddcf7ca42d9f5..2c5567175dca60f8bcf8c4e19e2eb78e66807fe9 100644 (file)
@@ -139,12 +139,8 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
 int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
                               u8 **out_edid)
 {
-       u32 reg = rinfo->i2c[conn-1].ddc_reg;
        u8 *edid;
 
-       OUTREG(reg, INREG(reg) &
-                       ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
-
        edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
 
        if (out_edid)
index 675abdafc2d8d047741ed3b8fdf2c0291343440c..3df5015f1d13f540a6bc9b5cbfdd663663604eac 100644 (file)
@@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 
        if (!(info->flags & FBINFO_HWACCEL_DISABLED)) {
                /* Make sure engine is reset */
-               radeon_engine_idle();
+               radeon_engine_idle(rinfo);
                radeonfb_engine_reset(rinfo);
-               radeon_engine_idle();
+               radeon_engine_idle(rinfo);
        }
 
        /* Blank display and LCD */
@@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
 
                rinfo->asleep = 0;
        } else
-               radeon_engine_idle();
+               radeon_engine_idle(rinfo);
 
        /* Restore display & engine */
        radeon_write_mode (rinfo, &rinfo->state, 1);
index ccbfffd128056c57392f02ff59f2dfe318f5b24e..ea0b5b47acaf437027b0a5b153dd6cc4c5d5e1b3 100644 (file)
@@ -53,6 +53,7 @@ enum radeon_family {
        CHIP_FAMILY_RV380,    /* RV370/RV380/M22/M24 */
        CHIP_FAMILY_R420,     /* R420/R423/M18 */
        CHIP_FAMILY_RC410,
+       CHIP_FAMILY_RS400,
        CHIP_FAMILY_RS480,
        CHIP_FAMILY_LAST,
 };
@@ -335,7 +336,15 @@ struct radeonfb_info {
        int                     mon2_type;
        u8                      *mon2_EDID;
 
-       u32                     dp_gui_master_cntl;
+       /* accel bits */
+       u32                     dp_gui_mc_base;
+       u32                     dp_gui_mc_cache;
+       u32                     dp_cntl_cache;
+       u32                     dp_brush_fg_cache;
+       u32                     dp_brush_bg_cache;
+       u32                     dp_src_fg_cache;
+       u32                     dp_src_bg_cache;
+       u32                     fifo_free;
 
        struct pll_info         pll;
 
@@ -347,6 +356,7 @@ struct radeonfb_info {
        int                     lock_blank;
        int                     dynclk;
        int                     no_schedule;
+       int                     gfx_mode;
        enum radeon_pm_mode     pm_mode;
        reinit_function_ptr     reinit_func;
 
@@ -391,8 +401,14 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
 #define OUTREG8(addr,val)      writeb(val, (rinfo->mmio_base)+addr)
 #define INREG16(addr)          readw((rinfo->mmio_base)+addr)
 #define OUTREG16(addr,val)     writew(val, (rinfo->mmio_base)+addr)
+
+#ifdef CONFIG_PPC
+#define INREG(addr)            ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); })
+#define OUTREG(addr,val)       do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0)
+#else
 #define INREG(addr)            readl((rinfo->mmio_base)+addr)
 #define OUTREG(addr,val)       writel(val, (rinfo->mmio_base)+addr)
+#endif
 
 static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
                       u32 val, u32 mask)
@@ -533,16 +549,25 @@ static inline u32 radeon_get_dstbpp(u16 depth)
 /*
  * 2D Engine helper routines
  */
+
+extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries);
+
 static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
 {
        int i;
 
-       /* initiate flush */
-       OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+       /* Initiate flush */
+       OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
                ~RB2D_DC_FLUSH_ALL);
 
+       /* Ensure FIFO is empty, ie, make sure the flush commands
+        * has reached the cache
+        */
+       radeon_fifo_update_and_wait(rinfo, 64);
+
+       /* Wait for the flush to complete */
        for (i=0; i < 2000000; i++) {
-               if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+               if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
                        return;
                udelay(1);
        }
@@ -550,25 +575,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
 }
 
 
-static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
-{
-       int i;
-
-       for (i=0; i<2000000; i++) {
-               if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
-                       return;
-               udelay(1);
-       }
-       printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
-}
-
-
-static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
+static inline void radeon_engine_idle(struct radeonfb_info *rinfo)
 {
        int i;
 
        /* ensure FIFO is empty before waiting for idle */
-       _radeon_fifo_wait (rinfo, 64);
+       radeon_fifo_update_and_wait (rinfo, 64);
 
        for (i=0; i<2000000; i++) {
                if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
@@ -581,8 +593,6 @@ static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
 }
 
 
-#define radeon_engine_idle()           _radeon_engine_idle(rinfo)
-#define radeon_fifo_wait(entries)      _radeon_fifo_wait(rinfo,entries)
 #define radeon_msleep(ms)              _radeon_msleep(rinfo,ms)
 
 
@@ -612,6 +622,7 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image);
 extern int radeonfb_sync(struct fb_info *info);
 extern void radeonfb_engine_init (struct radeonfb_info *rinfo);
 extern void radeonfb_engine_reset(struct radeonfb_info *rinfo);
+extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo);
 
 /* Other functions */
 extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch);
index e15bb447440a54c21d3b772e4deb51012cd27dbb..c9b191319a9a6ca7cdd047d52fd5e38918db6176 100644 (file)
@@ -535,7 +535,7 @@ static struct fb_ops carminefb_ops = {
        .fb_setcolreg   = carmine_setcolreg,
 };
 
-static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
+static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
                int smem_offset, struct device *device, struct fb_info **rinfo)
 {
        int ret;
index e729fb279645dd34f634be1fb0ddaea60396a7bb..048b139f0e50ce67eaa85d8d228f74fd40a72038 100644 (file)
@@ -327,29 +327,7 @@ static const struct {
 #endif /* CONFIG_ZORRO */
 
 struct cirrusfb_regs {
-       long freq;
-       long nom;
-       long den;
-       long div;
-       long multiplexing;
-       long mclk;
-       long divMCLK;
-
-       long HorizRes;          /* The x resolution in pixel */
-       long HorizTotal;
-       long HorizDispEnd;
-       long HorizBlankStart;
-       long HorizBlankEnd;
-       long HorizSyncStart;
-       long HorizSyncEnd;
-
-       long VertRes;           /* the physical y resolution in scanlines */
-       long VertTotal;
-       long VertDispEnd;
-       long VertSyncStart;
-       long VertSyncEnd;
-       long VertBlankStart;
-       long VertBlankEnd;
+       int multiplexing;
 };
 
 #ifdef CIRRUSFB_DEBUG
@@ -367,110 +345,13 @@ struct cirrusfb_info {
 
        struct cirrusfb_regs currentmode;
        int blank_mode;
+       u32 pseudo_palette[16];
 
-       u32     pseudo_palette[16];
-
-#ifdef CONFIG_ZORRO
-       struct zorro_dev *zdev;
-#endif
-#ifdef CONFIG_PCI
-       struct pci_dev *pdev;
-#endif
        void (*unmap)(struct fb_info *info);
 };
 
-static unsigned cirrusfb_def_mode = 1;
-static int noaccel;
-
-/*
- *    Predefined Video Modes
- */
-
-static const struct {
-       const char *name;
-       struct fb_var_screeninfo var;
-} cirrusfb_predefined[] = {
-       {
-               /* autodetect mode */
-               .name   = "Autodetect",
-       }, {
-               /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
-               .name   = "640x480",
-               .var    = {
-                       .xres           = 640,
-                       .yres           = 480,
-                       .xres_virtual   = 640,
-                       .yres_virtual   = 480,
-                       .bits_per_pixel = 8,
-                       .red            = { .length = 8 },
-                       .green          = { .length = 8 },
-                       .blue           = { .length = 8 },
-                       .width          = -1,
-                       .height         = -1,
-                       .pixclock       = 40000,
-                       .left_margin    = 48,
-                       .right_margin   = 16,
-                       .upper_margin   = 32,
-                       .lower_margin   = 8,
-                       .hsync_len      = 96,
-                       .vsync_len      = 4,
-                       .sync   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-                       .vmode          = FB_VMODE_NONINTERLACED
-                }
-       }, {
-               /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
-               .name   = "800x600",
-               .var    = {
-                       .xres           = 800,
-                       .yres           = 600,
-                       .xres_virtual   = 800,
-                       .yres_virtual   = 600,
-                       .bits_per_pixel = 8,
-                       .red            = { .length = 8 },
-                       .green          = { .length = 8 },
-                       .blue           = { .length = 8 },
-                       .width          = -1,
-                       .height         = -1,
-                       .pixclock       = 20000,
-                       .left_margin    = 128,
-                       .right_margin   = 16,
-                       .upper_margin   = 24,
-                       .lower_margin   = 2,
-                       .hsync_len      = 96,
-                       .vsync_len      = 6,
-                       .vmode          = FB_VMODE_NONINTERLACED
-                }
-       }, {
-               /*
-                * Modeline from XF86Config:
-                * Mode "1024x768" 80  1024 1136 1340 1432  768 770 774 805
-                */
-               /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
-               .name   = "1024x768",
-               .var    = {
-                       .xres           = 1024,
-                       .yres           = 768,
-                       .xres_virtual   = 1024,
-                       .yres_virtual   = 768,
-                       .bits_per_pixel = 8,
-                       .red            = { .length = 8 },
-                       .green          = { .length = 8 },
-                       .blue           = { .length = 8 },
-                       .width          = -1,
-                       .height         = -1,
-                       .pixclock       = 12500,
-                       .left_margin    = 144,
-                       .right_margin   = 32,
-                       .upper_margin   = 30,
-                       .lower_margin   = 2,
-                       .hsync_len      = 192,
-                       .vsync_len      = 6,
-                       .vmode          = FB_VMODE_NONINTERLACED
-               }
-       }
-};
-
-#define NUM_TOTAL_MODES    ARRAY_SIZE(cirrusfb_predefined)
+static int noaccel __devinitdata;
+static char *mode_option __devinitdata = "640x480@60";
 
 /****************************************************************************/
 /**** BEGIN PROTOTYPES ******************************************************/
@@ -514,10 +395,6 @@ static struct fb_ops cirrusfb_ops = {
        .fb_imageblit   = cirrusfb_imageblit,
 };
 
-/*--- Hardware Specific Routines -------------------------------------------*/
-static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
-                               struct cirrusfb_regs *regs,
-                               struct fb_info *info);
 /*--- Internal routines ----------------------------------------------------*/
 static void init_vgachip(struct fb_info *info);
 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
@@ -546,9 +423,7 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
                              u_short width, u_short height,
                              u_char color, u_short line_length);
 
-static void bestclock(long freq, long *best,
-                     long *nom, long *den,
-                     long *div, long maxfreq);
+static void bestclock(long freq, int *nom, int *den, int *div);
 
 #ifdef CIRRUSFB_DEBUG
 static void cirrusfb_dump(void);
@@ -584,45 +459,28 @@ static int cirrusfb_release(struct fb_info *info, int user)
 /****************************************************************************/
 /**** BEGIN Hardware specific Routines **************************************/
 
-/* Get a good MCLK value */
-static long cirrusfb_get_mclk(long freq, int bpp, long *div)
+/* Check if the MCLK is not a better clock source */
+static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq)
 {
-       long mclk;
+       long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
 
-       assert(div != NULL);
-
-       /* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
-        * Assume a 64-bit data path for now.  The formula is:
-        * ((B * PCLK * 2)/W) * 1.2
-        * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
-       mclk = ((bpp / 8) * freq * 2) / 4;
-       mclk = (mclk * 12) / 10;
-       if (mclk < 50000)
-               mclk = 50000;
-       DPRINTK("Use MCLK of %ld kHz\n", mclk);
-
-       /* Calculate value for SR1F.  Multiply by 2 so we can round up. */
-       mclk = ((mclk * 16) / 14318);
-       mclk = (mclk + 1) / 2;
-       DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
+       /* Read MCLK value */
+       mclk = (14318 * mclk) >> 3;
+       DPRINTK("Read MCLK of %ld kHz\n", mclk);
 
        /* Determine if we should use MCLK instead of VCLK, and if so, what we
-          * should divide it by to get VCLK */
-       switch (freq) {
-       case 24751 ... 25249:
-               *div = 2;
-               DPRINTK("Using VCLK = MCLK/2\n");
-               break;
-       case 49501 ... 50499:
-               *div = 1;
+        * should divide it by to get VCLK
+        */
+
+       if (abs(freq - mclk) < 250) {
                DPRINTK("Using VCLK = MCLK\n");
-               break;
-       default:
-               *div = 0;
-               break;
+               return 1;
+       } else if (abs(freq - (mclk / 2)) < 250) {
+               DPRINTK("Using VCLK = MCLK/2\n");
+               return 2;
        }
 
-       return mclk;
+       return 0;
 }
 
 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
@@ -638,7 +496,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
                break;          /* 8 pixel per byte, only 1/4th of mem usable */
        case 8:
        case 16:
-       case 24:
        case 32:
                break;          /* 1 pixel == 1 byte */
        default:
@@ -713,7 +570,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
                var->blue.length = 5;
                break;
 
-       case 24:
        case 32:
                if (isPReP) {
                        var->red.offset = 8;
@@ -767,8 +623,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
        long maxclock;
        int maxclockidx = var->bits_per_pixel >> 3;
        struct cirrusfb_info *cinfo = info->par;
-       int xres, hfront, hsync, hback;
-       int yres, vfront, vsync, vback;
 
        switch (var->bits_per_pixel) {
        case 1:
@@ -782,10 +636,9 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
                break;
 
        case 16:
-       case 24:
        case 32:
                info->fix.line_length = var->xres_virtual * maxclockidx;
-               info->fix.visual = FB_VISUAL_DIRECTCOLOR;
+               info->fix.visual = FB_VISUAL_TRUECOLOR;
                break;
 
        default:
@@ -827,90 +680,33 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
        switch (var->bits_per_pixel) {
        case 16:
        case 32:
-               if (regs->HorizRes <= 800)
+               if (var->xres <= 800)
                        /* Xbh has this type of clock for 32-bit */
                        freq /= 2;
                break;
        }
 #endif
-
-       bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
-                 maxclock);
-       regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
-                                       &regs->divMCLK);
-
-       xres = var->xres;
-       hfront = var->right_margin;
-       hsync = var->hsync_len;
-       hback = var->left_margin;
-
-       yres = var->yres;
-       vfront = var->lower_margin;
-       vsync = var->vsync_len;
-       vback = var->upper_margin;
-
-       if (var->vmode & FB_VMODE_DOUBLE) {
-               yres *= 2;
-               vfront *= 2;
-               vsync *= 2;
-               vback *= 2;
-       } else if (var->vmode & FB_VMODE_INTERLACED) {
-               yres = (yres + 1) / 2;
-               vfront = (vfront + 1) / 2;
-               vsync = (vsync + 1) / 2;
-               vback = (vback + 1) / 2;
-       }
-       regs->HorizRes = xres;
-       regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
-       regs->HorizDispEnd = xres / 8 - 1;
-       regs->HorizBlankStart = xres / 8;
-       /* does not count with "-5" */
-       regs->HorizBlankEnd = regs->HorizTotal + 5;
-       regs->HorizSyncStart = (xres + hfront) / 8 + 1;
-       regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
-
-       regs->VertRes = yres;
-       regs->VertTotal = yres + vfront + vsync + vback - 2;
-       regs->VertDispEnd = yres - 1;
-       regs->VertBlankStart = yres;
-       regs->VertBlankEnd = regs->VertTotal;
-       regs->VertSyncStart = yres + vfront - 1;
-       regs->VertSyncEnd = yres + vfront + vsync - 1;
-
-       if (regs->VertRes >= 1024) {
-               regs->VertTotal /= 2;
-               regs->VertSyncStart /= 2;
-               regs->VertSyncEnd /= 2;
-               regs->VertDispEnd /= 2;
-       }
-       if (regs->multiplexing) {
-               regs->HorizTotal /= 2;
-               regs->HorizSyncStart /= 2;
-               regs->HorizSyncEnd /= 2;
-               regs->HorizDispEnd /= 2;
-       }
-
        return 0;
 }
 
-static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
-                               int div)
+static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo,
+                                       int div)
 {
+       unsigned char old1f, old1e;
        assert(cinfo != NULL);
+       old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
 
-       if (div == 2) {
-               /* VCLK = MCLK/2 */
-               unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
-               vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
-               vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
-       } else if (div == 1) {
-               /* VCLK = MCLK */
-               unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
-               vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
-               vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
-       } else {
-               vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
+       if (div) {
+               DPRINTK("Set %s as pixclock source.\n",
+                                       (div == 2) ? "MCLK/2" : "MCLK");
+               old1f |= 0x40;
+               old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
+               if (div == 2)
+                       old1e |= 1;
+
+               vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
        }
+       vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
 }
 
 /*************************************************************************
@@ -927,6 +723,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
        unsigned char tmp;
        int offset = 0, err;
        const struct cirrusfb_board_info_rec *bi;
+       int hdispend, hsyncstart, hsyncend, htotal;
+       int yres, vdispend, vsyncstart, vsyncend, vtotal;
+       long freq;
+       int nom, den, div;
 
        DPRINTK("ENTER\n");
        DPRINTK("Requested mode: %dx%dx%d\n",
@@ -944,76 +744,117 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
 
        bi = &cirrusfb_board_info[cinfo->btype];
 
+       hsyncstart = var->xres + var->right_margin;
+       hsyncend = hsyncstart + var->hsync_len;
+       htotal = (hsyncend + var->left_margin) / 8 - 5;
+       hdispend = var->xres / 8 - 1;
+       hsyncstart = hsyncstart / 8 + 1;
+       hsyncend = hsyncend / 8 + 1;
+
+       yres = var->yres;
+       vsyncstart = yres + var->lower_margin;
+       vsyncend = vsyncstart + var->vsync_len;
+       vtotal = vsyncend + var->upper_margin;
+       vdispend = yres - 1;
+
+       if (var->vmode & FB_VMODE_DOUBLE) {
+               yres *= 2;
+               vsyncstart *= 2;
+               vsyncend *= 2;
+               vtotal *= 2;
+       } else if (var->vmode & FB_VMODE_INTERLACED) {
+               yres = (yres + 1) / 2;
+               vsyncstart = (vsyncstart + 1) / 2;
+               vsyncend = (vsyncend + 1) / 2;
+               vtotal = (vtotal + 1) / 2;
+       }
+
+       vtotal -= 2;
+       vsyncstart -= 1;
+       vsyncend -= 1;
+
+       if (yres >= 1024) {
+               vtotal /= 2;
+               vsyncstart /= 2;
+               vsyncend /= 2;
+               vdispend /= 2;
+       }
+       if (regs.multiplexing) {
+               htotal /= 2;
+               hsyncstart /= 2;
+               hsyncend /= 2;
+               hdispend /= 2;
+       }
        /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
        vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);   /* previously: 0x00) */
 
        /* if debugging is enabled, all parameters get output before writing */
-       DPRINTK("CRT0: %ld\n", regs.HorizTotal);
-       vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
+       DPRINTK("CRT0: %d\n", htotal);
+       vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
 
-       DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
-       vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
+       DPRINTK("CRT1: %d\n", hdispend);
+       vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
 
-       DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
-       vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
+       DPRINTK("CRT2: %d\n", var->xres / 8);
+       vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
 
        /*  + 128: Compatible read */
-       DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
+       DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32);
        vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
-                128 + (regs.HorizBlankEnd % 32));
+                128 + ((htotal + 5) % 32));
 
-       DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
-       vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
+       DPRINTK("CRT4: %d\n", hsyncstart);
+       vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
 
-       tmp = regs.HorizSyncEnd % 32;
-       if (regs.HorizBlankEnd & 32)
+       tmp = hsyncend % 32;
+       if ((htotal + 5) & 32)
                tmp += 128;
        DPRINTK("CRT5: %d\n", tmp);
        vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
 
-       DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
-       vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
+       DPRINTK("CRT6: %d\n", vtotal & 0xff);
+       vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
 
        tmp = 16;               /* LineCompare bit #9 */
-       if (regs.VertTotal & 256)
+       if (vtotal & 256)
                tmp |= 1;
-       if (regs.VertDispEnd & 256)
+       if (vdispend & 256)
                tmp |= 2;
-       if (regs.VertSyncStart & 256)
+       if (vsyncstart & 256)
                tmp |= 4;
-       if (regs.VertBlankStart & 256)
+       if ((vdispend + 1) & 256)
                tmp |= 8;
-       if (regs.VertTotal & 512)
+       if (vtotal & 512)
                tmp |= 32;
-       if (regs.VertDispEnd & 512)
+       if (vdispend & 512)
                tmp |= 64;
-       if (regs.VertSyncStart & 512)
+       if (vsyncstart & 512)
                tmp |= 128;
        DPRINTK("CRT7: %d\n", tmp);
        vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
 
        tmp = 0x40;             /* LineCompare bit #8 */
-       if (regs.VertBlankStart & 512)
+       if ((vdispend + 1) & 512)
                tmp |= 0x20;
        if (var->vmode & FB_VMODE_DOUBLE)
                tmp |= 0x80;
        DPRINTK("CRT9: %d\n", tmp);
        vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
 
-       DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
-       vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
+       DPRINTK("CRT10: %d\n", vsyncstart & 0xff);
+       vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
 
-       DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
-       vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
+       DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16);
+       vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
 
-       DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
-       vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
+       DPRINTK("CRT12: %d\n", vdispend & 0xff);
+       vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
 
-       DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
-       vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
+       DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff);
+       vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
 
-       DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
-       vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
+       DPRINTK("CRT16: %d\n", vtotal & 0xff);
+       vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
 
        DPRINTK("CRT18: 0xff\n");
        vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
@@ -1021,38 +862,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
        tmp = 0;
        if (var->vmode & FB_VMODE_INTERLACED)
                tmp |= 1;
-       if (regs.HorizBlankEnd & 64)
+       if ((htotal + 5) & 64)
                tmp |= 16;
-       if (regs.HorizBlankEnd & 128)
+       if ((htotal + 5) & 128)
                tmp |= 32;
-       if (regs.VertBlankEnd & 256)
+       if (vtotal & 256)
                tmp |= 64;
-       if (regs.VertBlankEnd & 512)
+       if (vtotal & 512)
                tmp |= 128;
 
        DPRINTK("CRT1a: %d\n", tmp);
        vga_wcrt(regbase, CL_CRT1A, tmp);
 
+       freq = PICOS2KHZ(var->pixclock);
+       bestclock(freq, &nom, &den, &div);
+
        /* set VCLK0 */
        /* hardware RefClock: 14.31818 MHz */
        /* formula: VClk = (OSC * N) / (D * (1+P)) */
        /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
 
-       vga_wseq(regbase, CL_SEQRB, regs.nom);
-       tmp = regs.den << 1;
-       if (regs.div != 0)
-               tmp |= 1;
+       if (cinfo->btype == BT_ALPINE) {
+               /* if freq is close to mclk or mclk/2 select mclk
+                * as clock source
+                */
+               int divMCLK = cirrusfb_check_mclk(cinfo, freq);
+               if (divMCLK)  {
+                       nom = 0;
+                       cirrusfb_set_mclk_as_source(cinfo, divMCLK);
+               }
+       }
+       if (nom) {
+               vga_wseq(regbase, CL_SEQRB, nom);
+               tmp = den << 1;
+               if (div != 0)
+                       tmp |= 1;
 
-       /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
-       if ((cinfo->btype == BT_SD64) ||
-           (cinfo->btype == BT_ALPINE) ||
-           (cinfo->btype == BT_GD5480))
-               tmp |= 0x80;
+               /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
+               if ((cinfo->btype == BT_SD64) ||
+                   (cinfo->btype == BT_ALPINE) ||
+                   (cinfo->btype == BT_GD5480))
+                       tmp |= 0x80;
 
-       DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
-       vga_wseq(regbase, CL_SEQR1B, tmp);
+               DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
+               vga_wseq(regbase, CL_SEQR1B, tmp);
+       }
 
-       if (regs.VertRes >= 1024)
+       if (yres >= 1024)
                /* 1280x1024 */
                vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
        else
@@ -1066,7 +922,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
        /* don't know if it would hurt to also program this if no interlaced */
        /* mode is used, but I feel better this way.. :-) */
        if (var->vmode & FB_VMODE_INTERLACED)
-               vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
+               vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
        else
                vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
 
@@ -1240,7 +1096,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
 
                case BT_ALPINE:
                        DPRINTK(" (for GD543x)\n");
-                       cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
                        /* We already set SRF and SR1F */
                        break;
 
@@ -1312,11 +1167,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
 
                case BT_ALPINE:
                        DPRINTK(" (for GD543x)\n");
-                       if (regs.HorizRes >= 1024)
-                               vga_wseq(regbase, CL_SEQR7, 0xa7);
-                       else
-                               vga_wseq(regbase, CL_SEQR7, 0xa3);
-                       cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
+                       vga_wseq(regbase, CL_SEQR7, 0xa7);
                        break;
 
                case BT_GD5480:
@@ -1360,7 +1211,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
         */
 
        else if (var->bits_per_pixel == 32) {
-               DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n");
+               DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
                switch (cinfo->btype) {
                case BT_SD64:
                        /* Extended Sequencer Mode: 256c col. mode */
@@ -1394,7 +1245,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                case BT_ALPINE:
                        DPRINTK(" (for GD543x)\n");
                        vga_wseq(regbase, CL_SEQR7, 0xa9);
-                       cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
                        break;
 
                case BT_GD5480:
@@ -1949,8 +1799,6 @@ static void init_vgachip(struct fb_info *info)
        /* misc... */
        WHDR(cinfo, 0); /* Hidden DAC register: - */
 
-       printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
-               info->screen_size);
        DPRINTK("EXIT\n");
        return;
 }
@@ -2122,7 +1970,7 @@ static int release_io_ports;
  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
  * seem to have. */
-static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
+static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase)
 {
        unsigned long mem;
        unsigned char SRF;
@@ -2188,8 +2036,7 @@ static void get_pci_addrs(const struct pci_dev *pdev,
 
 static void cirrusfb_pci_unmap(struct fb_info *info)
 {
-       struct cirrusfb_info *cinfo = info->par;
-       struct pci_dev *pdev = cinfo->pdev;
+       struct pci_dev *pdev = to_pci_dev(info->device);
 
        iounmap(info->screen_base);
 #if 0 /* if system didn't claim this region, we would... */
@@ -2205,20 +2052,22 @@ static void cirrusfb_pci_unmap(struct fb_info *info)
 static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
-       zorro_release_device(cinfo->zdev);
+       struct zorro_dev *zdev = to_zorro_dev(info->device);
+
+       zorro_release_device(zdev);
 
        if (cinfo->btype == BT_PICASSO4) {
                cinfo->regbase -= 0x600000;
                iounmap((void *)cinfo->regbase);
                iounmap(info->screen_base);
        } else {
-               if (zorro_resource_start(cinfo->zdev) > 0x01000000)
+               if (zorro_resource_start(zdev) > 0x01000000)
                        iounmap(info->screen_base);
        }
 }
 #endif /* CONFIG_ZORRO */
 
-static int cirrusfb_set_fbinfo(struct fb_info *info)
+static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
        struct fb_var_screeninfo *var = &info->var;
@@ -2235,7 +2084,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
        if (cinfo->btype == BT_GD5480) {
                if (var->bits_per_pixel == 16)
                        info->screen_base += 1 * MB_;
-               if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32)
+               if (var->bits_per_pixel == 32)
                        info->screen_base += 2 * MB_;
        }
 
@@ -2262,7 +2111,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
        return 0;
 }
 
-static int cirrusfb_register(struct fb_info *info)
+static int __devinit cirrusfb_register(struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
        int err;
@@ -2278,23 +2127,27 @@ static int cirrusfb_register(struct fb_info *info)
        /* sanity checks */
        assert(btype != BT_NONE);
 
+       /* set all the vital stuff */
+       cirrusfb_set_fbinfo(info);
+
        DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
 
-       /* Make pretend we've set the var so our structures are in a "good" */
-       /* state, even though we haven't written the mode to the hw yet...  */
-       info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
+       err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
+       if (!err) {
+               DPRINTK("wrong initial video mode\n");
+               err = -EINVAL;
+               goto err_dealloc_cmap;
+       }
+
        info->var.activate = FB_ACTIVATE_NOW;
 
        err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
        if (err < 0) {
                /* should never happen */
                DPRINTK("choking on default var... umm, no good.\n");
-               goto err_unmap_cirrusfb;
+               goto err_dealloc_cmap;
        }
 
-       /* set all the vital stuff */
-       cirrusfb_set_fbinfo(info);
-
        err = register_framebuffer(info);
        if (err < 0) {
                printk(KERN_ERR "cirrusfb: could not register "
@@ -2307,7 +2160,6 @@ static int cirrusfb_register(struct fb_info *info)
 
 err_dealloc_cmap:
        fb_dealloc_cmap(&info->cmap);
-err_unmap_cirrusfb:
        cinfo->unmap(info);
        framebuffer_release(info);
        return err;
@@ -2330,8 +2182,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
 }
 
 #ifdef CONFIG_PCI
-static int cirrusfb_pci_register(struct pci_dev *pdev,
-                                 const struct pci_device_id *ent)
+static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
+                                          const struct pci_device_id *ent)
 {
        struct cirrusfb_info *cinfo;
        struct fb_info *info;
@@ -2353,7 +2205,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
        }
 
        cinfo = info->par;
-       cinfo->pdev = pdev;
        cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
 
        DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
@@ -2459,8 +2310,8 @@ static struct pci_driver cirrusfb_pci_driver = {
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_ZORRO
-static int cirrusfb_zorro_register(struct zorro_dev *z,
-                                  const struct zorro_device_id *ent)
+static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
+                                            const struct zorro_device_id *ent)
 {
        struct cirrusfb_info *cinfo;
        struct fb_info *info;
@@ -2489,7 +2340,6 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
        assert(z);
        assert(btype != BT_NONE);
 
-       cinfo->zdev = z;
        board_addr = zorro_resource_start(z);
        board_size = zorro_resource_len(z);
        info->screen_size = size;
@@ -2621,17 +2471,17 @@ static int __init cirrusfb_setup(char *options) {
                return 0;
 
        while ((this_opt = strsep(&options, ",")) != NULL) {
-               if (!*this_opt) continue;
+               if (!*this_opt)
+                       continue;
 
                DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
 
-               for (i = 0; i < NUM_TOTAL_MODES; i++) {
-                       sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
-                       if (strcmp(this_opt, s) == 0)
-                               cirrusfb_def_mode = i;
-               }
                if (!strcmp(this_opt, "noaccel"))
                        noaccel = 1;
+               else if (!strncmp(this_opt, "mode:", 5))
+                       mode_option = this_opt + 5;
+               else
+                       mode_option = this_opt;
        }
        return 0;
 }
@@ -2657,6 +2507,11 @@ static void __exit cirrusfb_exit(void)
 
 module_init(cirrusfb_init);
 
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
+module_param(noaccel, bool, 0);
+MODULE_PARM_DESC(noaccel, "Disable acceleration");
+
 #ifdef MODULE
 module_exit(cirrusfb_exit);
 #endif
@@ -3050,16 +2905,14 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
  * bestclock() - determine closest possible clock lower(?) than the
  * desired pixel clock
  **************************************************************************/
-static void bestclock(long freq, long *best, long *nom,
-                      long *den, long *div, long maxfreq)
+static void bestclock(long freq, int *nom, int *den, int *div)
 {
-       long n, h, d, f;
+       int n, d;
+       long h, diff;
 
-       assert(best != NULL);
        assert(nom != NULL);
        assert(den != NULL);
        assert(div != NULL);
-       assert(maxfreq > 0);
 
        *nom = 0;
        *den = 0;
@@ -3070,51 +2923,47 @@ static void bestclock(long freq, long *best, long *nom,
        if (freq < 8000)
                freq = 8000;
 
-       if (freq > maxfreq)
-               freq = maxfreq;
-
-       *best = 0;
-       f = freq * 10;
+       diff = freq;
 
        for (n = 32; n < 128; n++) {
-               d = (143181 * n) / f;
+               int s = 0;
+
+               d = (14318 * n) / freq;
                if ((d >= 7) && (d <= 63)) {
-                       if (d > 31)
-                               d = (d / 2) * 2;
-                       h = (14318 * n) / d;
-                       if (abs(h - freq) < abs(*best - freq)) {
-                               *best = h;
+                       int temp = d;
+
+                       if (temp > 31) {
+                               s = 1;
+                               temp >>= 1;
+                       }
+                       h = ((14318 * n) / temp) >> s;
+                       h = h > freq ? h - freq : freq - h;
+                       if (h < diff) {
+                               diff = h;
                                *nom = n;
-                               if (d < 32) {
-                                       *den = d;
-                                       *div = 0;
-                               } else {
-                                       *den = d / 2;
-                                       *div = 1;
-                               }
+                               *den = temp;
+                               *div = s;
                        }
                }
-               d = DIV_ROUND_UP(143181 * n, f);
+               d++;
                if ((d >= 7) && (d <= 63)) {
-                       if (d > 31)
-                               d = (d / 2) * 2;
-                       h = (14318 * n) / d;
-                       if (abs(h - freq) < abs(*best - freq)) {
-                               *best = h;
+                       if (d > 31) {
+                               s = 1;
+                               d >>= 1;
+                       }
+                       h = ((14318 * n) / d) >> s;
+                       h = h > freq ? h - freq : freq - h;
+                       if (h < diff) {
+                               diff = h;
                                *nom = n;
-                               if (d < 32) {
-                                       *den = d;
-                                       *div = 0;
-                               } else {
-                                       *den = d / 2;
-                                       *div = 1;
-                               }
+                               *den = d;
+                               *div = s;
                        }
                }
        }
 
        DPRINTK("Best possible values for given frequency:\n");
-       DPRINTK("       best: %ld kHz  nom: %ld  den: %ld  div: %ld\n",
+       DPRINTK("       freq: %ld kHz  nom: %d  den: %d  div: %d\n",
                freq, *nom, *den, *div);
 
        DPRINTK("EXIT\n");
index da91bb16da8a1c530b7d4e7edccaef928876fee6..64b3d30027b825395ee2320f70c2e33f7665a0cf 100644 (file)
@@ -2977,8 +2977,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
                p = &fb_display[vc->vc_num];
                set_blitting_type(vc, info);
                var_to_display(p, &info->var, info);
-               cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
-               rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
+               cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+               rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
                cols /= vc->vc_font.width;
                rows /= vc->vc_font.height;
                vc_resize(vc, cols, rows);
@@ -3573,8 +3573,8 @@ static int __init fb_console_init(void)
 
        acquire_console_sem();
        fb_register_client(&fbcon_event_notifier);
-       fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0),
-                                            NULL, "fbcon");
+       fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
+                                    "fbcon");
 
        if (IS_ERR(fbcon_device)) {
                printk(KERN_WARNING "Unable to create device "
index 6df29a62d7202552d63ced7bfc588ef8854d6c49..448d209a0bf2109fa14af7d3c6a3b00e08c7df1b 100644 (file)
@@ -239,8 +239,7 @@ static void vgacon_restore_screen(struct vc_data *c)
 
 static int vgacon_scrolldelta(struct vc_data *c, int lines)
 {
-       int start, end, count, soff, diff;
-       void *d, *s;
+       int start, end, count, soff;
 
        if (!lines) {
                c->vc_visible_origin = c->vc_origin;
@@ -287,29 +286,29 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
        if (count > c->vc_rows)
                count = c->vc_rows;
 
-       diff = c->vc_rows - count;
+       if (count) {
+               int copysize;
 
-       d = (void *) c->vc_origin;
-       s = (void *) c->vc_screenbuf;
+               int diff = c->vc_rows - count;
+               void *d = (void *) c->vc_origin;
+               void *s = (void *) c->vc_screenbuf;
 
-       while (count--) {
-               scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row);
-               d += c->vc_size_row;
-               soff += c->vc_size_row;
+               count *= c->vc_size_row;
+               /* how much memory to end of buffer left? */
+               copysize = min(count, vgacon_scrollback_size - soff);
+               scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+               d += copysize;
+               count -= copysize;
 
-               if (soff >= vgacon_scrollback_size)
-                       soff = 0;
-       }
+               if (count) {
+                       scr_memcpyw(d, vgacon_scrollback, count);
+                       d += count;
+               }
 
-       if (diff == c->vc_rows) {
+               if (diff)
+                       scr_memcpyw(d, s, diff * c->vc_size_row);
+       } else
                vgacon_cursor(c, CM_MOVE);
-       } else {
-               while (diff--) {
-                       scr_memcpyw(d, s, c->vc_size_row);
-                       d += c->vc_size_row;
-                       s += c->vc_size_row;
-               }
-       }
 
        return 1;
 }
index 6ef800bdf4822f4fcf09f4e0e9db002b0d6fb9ba..4830b1bf51e5da7e6fcdadcfe67ce231ea977cc1 100644 (file)
@@ -153,12 +153,9 @@ struct display_device *display_device_register(struct display_driver *driver,
                mutex_unlock(&allocated_dsp_lock);
 
                if (!ret) {
-                       new_dev->dev = device_create_drvdata(display_class,
-                                                            parent,
-                                                            MKDEV(0,0),
-                                                            new_dev,
-                                                            "display%d",
-                                                            new_dev->idx);
+                       new_dev->dev = device_create(display_class, parent,
+                                                    MKDEV(0, 0), new_dev,
+                                                    "display%d", new_dev->idx);
                        if (!IS_ERR(new_dev->dev)) {
                                new_dev->parent = parent;
                                new_dev->driver = driver;
index bd779ae44b1e21ba90787b4fd5d70c0dc14694fe..daf9b81878a463a62bb81427f8e2e97c1978c2e3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/fb.h>
 #include <linux/platform_device.h>
 #include <linux/screen_info.h>
+#include <linux/dmi.h>
 
 #include <video/vga.h>
 
@@ -33,6 +34,105 @@ static struct fb_fix_screeninfo efifb_fix __initdata = {
        .visual                 = FB_VISUAL_TRUECOLOR,
 };
 
+enum {
+       M_I17,          /* 17-Inch iMac */
+       M_I20,          /* 20-Inch iMac */
+       M_I20_SR,       /* 20-Inch iMac (Santa Rosa) */
+       M_I24,          /* 24-Inch iMac */
+       M_MINI,         /* Mac Mini */
+       M_MB,           /* MacBook */
+       M_MB_2,         /* MacBook, 2nd rev. */
+       M_MB_3,         /* MacBook, 3rd rev. */
+       M_MB_SR,        /* MacBook, 2nd gen, (Santa Rosa) */
+       M_MBA,          /* MacBook Air */
+       M_MBP,          /* MacBook Pro */
+       M_MBP_2,        /* MacBook Pro 2nd gen */
+       M_MBP_SR,       /* MacBook Pro (Santa Rosa) */
+       M_MBP_4,        /* MacBook Pro, 4th gen */
+       M_UNKNOWN       /* placeholder */
+};
+
+static struct efifb_dmi_info {
+       char *optname;
+       unsigned long base;
+       int stride;
+       int width;
+       int height;
+} dmi_list[] = {
+       [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 },
+       [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
+       [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
+       [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
+       [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
+       [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
+       [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
+       [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
+       [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
+       [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
+       [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
+       [M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
+};
+
+static int set_system(const struct dmi_system_id *id);
+
+#define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid)              \
+       { set_system, name, {                                   \
+               DMI_MATCH(DMI_BIOS_VENDOR, vendor),             \
+               DMI_MATCH(DMI_PRODUCT_NAME, name) },            \
+         &dmi_list[enumid] }
+
+static struct dmi_system_id __initdata dmi_system_table[] = {
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17),
+       /* At least one of these two will be right; maybe both? */
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20),
+       /* At least one of these two will be right; maybe both? */
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
+       /* At least one of these two will be right; maybe both? */
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB),
+       /* At least one of these two will be right; maybe both? */
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
+       EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
+       {},
+};
+
+static int set_system(const struct dmi_system_id *id)
+{
+       struct efifb_dmi_info *info = id->driver_data;
+       if (info->base == 0)
+               return -ENODEV;
+
+       printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
+                        "(%dx%d, stride %d)\n", id->ident,
+                        (void *)info->base, info->width, info->height,
+                        info->stride);
+
+       /* Trust the bootloader over the DMI tables */
+       if (screen_info.lfb_base == 0)
+               screen_info.lfb_base = info->base;
+       if (screen_info.lfb_linelength == 0)
+               screen_info.lfb_linelength = info->stride;
+       if (screen_info.lfb_width == 0)
+               screen_info.lfb_width = info->width;
+       if (screen_info.lfb_height == 0)
+               screen_info.lfb_height = info->height;
+
+       return 0;
+}
+
 static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
                           unsigned blue, unsigned transp,
                           struct fb_info *info)
@@ -67,6 +167,38 @@ static struct fb_ops efifb_ops = {
        .fb_imageblit   = cfb_imageblit,
 };
 
+static int __init efifb_setup(char *options)
+{
+       char *this_opt;
+       int i;
+
+       if (!options || !*options)
+               return 0;
+
+       while ((this_opt = strsep(&options, ",")) != NULL) {
+               if (!*this_opt) continue;
+
+               for (i = 0; i < M_UNKNOWN; i++) {
+                       if (!strcmp(this_opt, dmi_list[i].optname) &&
+                                       dmi_list[i].base != 0) {
+                               screen_info.lfb_base = dmi_list[i].base;
+                               screen_info.lfb_linelength = dmi_list[i].stride;
+                               screen_info.lfb_width = dmi_list[i].width;
+                               screen_info.lfb_height = dmi_list[i].height;
+                       }
+               }
+               if (!strncmp(this_opt, "base:", 5))
+                       screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
+               else if (!strncmp(this_opt, "stride:", 7))
+                       screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
+               else if (!strncmp(this_opt, "height:", 7))
+                       screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
+               else if (!strncmp(this_opt, "width:", 6))
+                       screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
+       }
+       return 0;
+}
+
 static int __init efifb_probe(struct platform_device *dev)
 {
        struct fb_info *info;
@@ -74,6 +206,26 @@ static int __init efifb_probe(struct platform_device *dev)
        unsigned int size_vmode;
        unsigned int size_remap;
        unsigned int size_total;
+       int request_succeeded = 0;
+
+       printk(KERN_INFO "efifb: probing for efifb\n");
+
+       if (!screen_info.lfb_depth)
+               screen_info.lfb_depth = 32;
+       if (!screen_info.pages)
+               screen_info.pages = 1;
+
+       /* just assume they're all unset if any are */
+       if (!screen_info.blue_size) {
+               screen_info.blue_size = 8;
+               screen_info.blue_pos = 0;
+               screen_info.green_size = 8;
+               screen_info.green_pos = 8;
+               screen_info.red_size = 8;
+               screen_info.red_pos = 16;
+               screen_info.rsvd_size = 8;
+               screen_info.rsvd_pos = 24;
+       }
 
        efifb_fix.smem_start = screen_info.lfb_base;
        efifb_defined.bits_per_pixel = screen_info.lfb_depth;
@@ -98,21 +250,25 @@ static int __init efifb_probe(struct platform_device *dev)
         *                 option to simply use size_total as that
         *                 wastes plenty of kernel address space. */
        size_remap  = size_vmode * 2;
-       if (size_remap < size_vmode)
-               size_remap = size_vmode;
        if (size_remap > size_total)
                size_remap = size_total;
+       if (size_remap % PAGE_SIZE)
+               size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
        efifb_fix.smem_len = size_remap;
 
-       if (!request_mem_region(efifb_fix.smem_start, size_total, "efifb"))
+       if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
+               request_succeeded = 1;
+       } else {
                /* We cannot make this fatal. Sometimes this comes from magic
                   spaces our resource handlers simply don't know about */
                printk(KERN_WARNING
                       "efifb: cannot reserve video memory at 0x%lx\n",
                        efifb_fix.smem_start);
+       }
 
        info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
        if (!info) {
+               printk(KERN_ERR "efifb: cannot allocate framebuffer\n");
                err = -ENOMEM;
                goto err_release_mem;
        }
@@ -125,7 +281,7 @@ static int __init efifb_probe(struct platform_device *dev)
                                "0x%x @ 0x%lx\n",
                        efifb_fix.smem_len, efifb_fix.smem_start);
                err = -EIO;
-               goto err_unmap;
+               goto err_release_fb;
        }
 
        printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -178,25 +334,27 @@ static int __init efifb_probe(struct platform_device *dev)
        info->fix = efifb_fix;
        info->flags = FBINFO_FLAG_DEFAULT;
 
-       if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
-               err = -ENOMEM;
+       if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
+               printk(KERN_ERR "efifb: cannot allocate colormap\n");
                goto err_unmap;
        }
-       if (register_framebuffer(info) < 0) {
-               err = -EINVAL;
+       if ((err = register_framebuffer(info)) < 0) {
+               printk(KERN_ERR "efifb: cannot register framebuffer\n");
                goto err_fb_dealoc;
        }
        printk(KERN_INFO "fb%d: %s frame buffer device\n",
-              info->node, info->fix.id);
+               info->node, info->fix.id);
        return 0;
 
 err_fb_dealoc:
        fb_dealloc_cmap(&info->cmap);
 err_unmap:
        iounmap(info->screen_base);
+err_release_fb:
        framebuffer_release(info);
 err_release_mem:
-       release_mem_region(efifb_fix.smem_start, size_total);
+       if (request_succeeded)
+               release_mem_region(efifb_fix.smem_start, size_total);
        return err;
 }
 
@@ -214,9 +372,22 @@ static struct platform_device efifb_device = {
 static int __init efifb_init(void)
 {
        int ret;
+       char *option = NULL;
 
        if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
                return -ENODEV;
+       dmi_check_system(dmi_system_table);
+
+       if (fb_get_options("efifb", &option))
+               return -ENODEV;
+       efifb_setup(option);
+
+       /* We don't get linelength from UGA Draw Protocol, only from
+        * EFI Graphics Protocol.  So if it's not in DMI, and it's not
+        * passed in from the user, we really can't use the framebuffer.
+        */
+       if (!screen_info.lfb_linelength)
+               return -ENODEV;
 
        ret = platform_driver_register(&efifb_driver);
 
index 0737570030f5e85459b4f926e3a4e8a7aaa09b3d..217c5118ae9e71818ea80014cb2b54cb8c63c707 100644 (file)
@@ -28,9 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/console.h>
-#ifdef CONFIG_KMOD
 #include <linux/kmod.h>
-#endif
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/efi.h>
@@ -837,13 +835,6 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
        return (cnt) ? cnt : err;
 }
 
-#ifdef CONFIG_KMOD
-static void try_to_load(int fb)
-{
-       request_module("fb%d", fb);
-}
-#endif /* CONFIG_KMOD */
-
 int
 fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
 {
@@ -1086,10 +1077,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                    return -EINVAL;
                if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
                    return -EINVAL;
-#ifdef CONFIG_KMOD
                if (!registered_fb[con2fb.framebuffer])
-                   try_to_load(con2fb.framebuffer);
-#endif /* CONFIG_KMOD */
+                   request_module("fb%d", con2fb.framebuffer);
                if (!registered_fb[con2fb.framebuffer])
                    return -EINVAL;
                event.info = info;
@@ -1327,10 +1316,8 @@ fb_open(struct inode *inode, struct file *file)
        if (fbidx >= FB_MAX)
                return -ENODEV;
        lock_kernel();
-#ifdef CONFIG_KMOD
        if (!(info = registered_fb[fbidx]))
-               try_to_load(fbidx);
-#endif /* CONFIG_KMOD */
+               request_module("fb%d", fbidx);
        if (!(info = registered_fb[fbidx])) {
                res = -ENODEV;
                goto out;
@@ -1443,9 +1430,8 @@ register_framebuffer(struct fb_info *fb_info)
                        break;
        fb_info->node = i;
 
-       fb_info->dev = device_create_drvdata(fb_class, fb_info->device,
-                                            MKDEV(FB_MAJOR, i), NULL,
-                                            "fb%d", i);
+       fb_info->dev = device_create(fb_class, fb_info->device,
+                                    MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
        if (IS_ERR(fb_info->dev)) {
                /* Not fatal */
                printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
index 6a0aa180c266e0b3d03e8cc2a4dc890f1605d329..5c1a2c01778fe6e195df9405d0409d7a1a2a09f9 100644 (file)
@@ -564,7 +564,13 @@ static void get_detailed_timing(unsigned char *block,
                mode->sync |= FB_SYNC_VERT_HIGH_ACT;
        mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
                                     (V_ACTIVE + V_BLANKING));
-       mode->vmode = 0;
+       if (INTERLACED) {
+               mode->yres *= 2;
+               mode->upper_margin *= 2;
+               mode->lower_margin *= 2;
+               mode->vsync_len *= 2;
+               mode->vmode |= FB_VMODE_INTERLACED;
+       }
        mode->flag = FB_MODE_IS_DETAILED;
 
        DPRINTK("      %d MHz ",  PIXEL_CLOCK/1000000);
index 9366ef2bb5f7c5748107fa2346daff6d263c9efa..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,376 +0,0 @@
-/*
- * framebuffer driver for Intel Based Mac's
- *
- * (c) 2006 Edgar Hucek <gimli@dark-green.com>
- * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/screen_info.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/dmi.h>
-#include <linux/efi.h>
-
-#include <asm/io.h>
-
-#include <video/vga.h>
-
-typedef enum _MAC_TYPE {
-       M_I17,
-       M_I20,
-       M_MINI,
-       M_MACBOOK,
-       M_UNKNOWN
-} MAC_TYPE;
-
-/* --------------------------------------------------------------------- */
-
-static struct fb_var_screeninfo imacfb_defined __initdata = {
-       .activate               = FB_ACTIVATE_NOW,
-       .height                 = -1,
-       .width                  = -1,
-       .right_margin           = 32,
-       .upper_margin           = 16,
-       .lower_margin           = 4,
-       .vsync_len              = 4,
-       .vmode                  = FB_VMODE_NONINTERLACED,
-};
-
-static struct fb_fix_screeninfo imacfb_fix __initdata = {
-       .id                     = "IMAC VGA",
-       .type                   = FB_TYPE_PACKED_PIXELS,
-       .accel                  = FB_ACCEL_NONE,
-       .visual                 = FB_VISUAL_TRUECOLOR,
-};
-
-static int inverse;
-static int model               = M_UNKNOWN;
-static int manual_height;
-static int manual_width;
-
-static int set_system(const struct dmi_system_id *id)
-{
-       printk(KERN_INFO "imacfb: %s detected - set system to %ld\n",
-               id->ident, (long)id->driver_data);
-
-       model = (long)id->driver_data;
-
-       return 0;
-}
-
-static struct dmi_system_id __initdata dmi_system_table[] = {
-       { set_system, "iMac4,1", {
-         DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
-         DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17},
-       { set_system, "MacBookPro1,1", {
-         DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
-         DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17},
-       { set_system, "MacBook1,1", {
-         DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
-         DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK},
-       { set_system, "Macmini1,1", {
-         DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
-         DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI},
-       {},
-};
-
-#define        DEFAULT_FB_MEM  1024*1024*16
-
-/* --------------------------------------------------------------------- */
-
-static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-                           unsigned blue, unsigned transp,
-                           struct fb_info *info)
-{
-       /*
-        *  Set a single color register. The values supplied are
-        *  already rounded down to the hardware's capabilities
-        *  (according to the entries in the `var' structure). Return
-        *  != 0 for invalid regno.
-        */
-
-       if (regno >= info->cmap.len)
-               return 1;
-
-       if (regno < 16) {
-               red   >>= 8;
-               green >>= 8;
-               blue  >>= 8;
-               ((u32 *)(info->pseudo_palette))[regno] =
-                       (red   << info->var.red.offset)   |
-                       (green << info->var.green.offset) |
-                       (blue  << info->var.blue.offset);
-       }
-       return 0;
-}
-
-static struct fb_ops imacfb_ops = {
-       .owner          = THIS_MODULE,
-       .fb_setcolreg   = imacfb_setcolreg,
-       .fb_fillrect    = cfb_fillrect,
-       .fb_copyarea    = cfb_copyarea,
-       .fb_imageblit   = cfb_imageblit,
-};
-
-static int __init imacfb_setup(char *options)
-{
-       char *this_opt;
-
-       if (!options || !*options)
-               return 0;
-
-       while ((this_opt = strsep(&options, ",")) != NULL) {
-               if (!*this_opt) continue;
-
-               if (!strcmp(this_opt, "inverse"))
-                       inverse = 1;
-               else if (!strcmp(this_opt, "i17"))
-                       model = M_I17;
-               else if (!strcmp(this_opt, "i20"))
-                       model = M_I20;
-               else if (!strcmp(this_opt, "mini"))
-                       model = M_MINI;
-               else if (!strcmp(this_opt, "macbook"))
-                       model = M_MACBOOK;
-               else if (!strncmp(this_opt, "height:", 7))
-                       manual_height = simple_strtoul(this_opt+7, NULL, 0);
-               else if (!strncmp(this_opt, "width:", 6))
-                       manual_width = simple_strtoul(this_opt+6, NULL, 0);
-       }
-       return 0;
-}
-
-static int __init imacfb_probe(struct platform_device *dev)
-{
-       struct fb_info *info;
-       int err;
-       unsigned int size_vmode;
-       unsigned int size_remap;
-       unsigned int size_total;
-
-       screen_info.lfb_depth = 32;
-       screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000;
-       screen_info.pages=1;
-       screen_info.blue_size = 8;
-       screen_info.blue_pos = 0;
-       screen_info.green_size = 8;
-       screen_info.green_pos = 8;
-       screen_info.red_size = 8;
-       screen_info.red_pos = 16;
-       screen_info.rsvd_size = 8;
-       screen_info.rsvd_pos = 24;
-
-       switch (model) {
-       case M_I17:
-               screen_info.lfb_width = 1440;
-               screen_info.lfb_height = 900;
-               screen_info.lfb_linelength = 1472 * 4;
-               screen_info.lfb_base = 0x80010000;
-               break;
-       case M_I20:
-               screen_info.lfb_width = 1680;
-               screen_info.lfb_height = 1050;
-               screen_info.lfb_linelength = 1728 * 4;
-               screen_info.lfb_base = 0x80010000;
-               break;
-       case M_MINI:
-               screen_info.lfb_width = 1024;
-               screen_info.lfb_height = 768;
-               screen_info.lfb_linelength = 2048 * 4;
-               screen_info.lfb_base = 0x80000000;
-               break;
-       case M_MACBOOK:
-               screen_info.lfb_width = 1280;
-               screen_info.lfb_height = 800;
-               screen_info.lfb_linelength = 2048 * 4;
-               screen_info.lfb_base = 0x80000000;
-               break;
-       }
-
-       /* if the user wants to manually specify height/width,
-          we will override the defaults */
-       /* TODO: eventually get auto-detection working */
-       if (manual_height > 0)
-               screen_info.lfb_height = manual_height;
-       if (manual_width > 0)
-               screen_info.lfb_width = manual_width;
-
-       imacfb_fix.smem_start = screen_info.lfb_base;
-       imacfb_defined.bits_per_pixel = screen_info.lfb_depth;
-       imacfb_defined.xres = screen_info.lfb_width;
-       imacfb_defined.yres = screen_info.lfb_height;
-       imacfb_fix.line_length = screen_info.lfb_linelength;
-
-       /*   size_vmode -- that is the amount of memory needed for the
-        *                 used video mode, i.e. the minimum amount of
-        *                 memory we need. */
-       size_vmode = imacfb_defined.yres * imacfb_fix.line_length;
-
-       /*   size_total -- all video memory we have. Used for
-        *                 entries, ressource allocation and bounds
-        *                 checking. */
-       size_total = screen_info.lfb_size * 65536;
-       if (size_total < size_vmode)
-               size_total = size_vmode;
-
-       /*   size_remap -- the amount of video memory we are going to
-        *                 use for imacfb.  With modern cards it is no
-        *                 option to simply use size_total as that
-        *                 wastes plenty of kernel address space. */
-       size_remap  = size_vmode * 2;
-       if (size_remap < size_vmode)
-               size_remap = size_vmode;
-       if (size_remap > size_total)
-               size_remap = size_total;
-       imacfb_fix.smem_len = size_remap;
-
-       if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
-               printk(KERN_WARNING
-                      "imacfb: cannot reserve video memory at 0x%lx\n",
-                       imacfb_fix.smem_start);
-               /* We cannot make this fatal. Sometimes this comes from magic
-                  spaces our resource handlers simply don't know about */
-       }
-
-       info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
-       if (!info) {
-               err = -ENOMEM;
-               goto err_release_mem;
-       }
-       info->pseudo_palette = info->par;
-       info->par = NULL;
-
-       info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len);
-       if (!info->screen_base) {
-               printk(KERN_ERR "imacfb: abort, cannot ioremap video memory "
-                               "0x%x @ 0x%lx\n",
-                       imacfb_fix.smem_len, imacfb_fix.smem_start);
-               err = -EIO;
-               goto err_unmap;
-       }
-
-       printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, "
-              "using %dk, total %dk\n",
-              imacfb_fix.smem_start, info->screen_base,
-              size_remap/1024, size_total/1024);
-       printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
-              imacfb_defined.xres, imacfb_defined.yres,
-              imacfb_defined.bits_per_pixel, imacfb_fix.line_length,
-              screen_info.pages);
-
-       imacfb_defined.xres_virtual = imacfb_defined.xres;
-       imacfb_defined.yres_virtual = imacfb_fix.smem_len /
-                                       imacfb_fix.line_length;
-       printk(KERN_INFO "imacfb: scrolling: redraw\n");
-       imacfb_defined.yres_virtual = imacfb_defined.yres;
-
-       /* some dummy values for timing to make fbset happy */
-       imacfb_defined.pixclock     = 10000000 / imacfb_defined.xres *
-                                       1000 / imacfb_defined.yres;
-       imacfb_defined.left_margin  = (imacfb_defined.xres / 8) & 0xf8;
-       imacfb_defined.hsync_len    = (imacfb_defined.xres / 8) & 0xf8;
-
-       imacfb_defined.red.offset    = screen_info.red_pos;
-       imacfb_defined.red.length    = screen_info.red_size;
-       imacfb_defined.green.offset  = screen_info.green_pos;
-       imacfb_defined.green.length  = screen_info.green_size;
-       imacfb_defined.blue.offset   = screen_info.blue_pos;
-       imacfb_defined.blue.length   = screen_info.blue_size;
-       imacfb_defined.transp.offset = screen_info.rsvd_pos;
-       imacfb_defined.transp.length = screen_info.rsvd_size;
-
-       printk(KERN_INFO "imacfb: %s: "
-              "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
-              "Truecolor",
-              screen_info.rsvd_size,
-              screen_info.red_size,
-              screen_info.green_size,
-              screen_info.blue_size,
-              screen_info.rsvd_pos,
-              screen_info.red_pos,
-              screen_info.green_pos,
-              screen_info.blue_pos);
-
-       imacfb_fix.ypanstep  = 0;
-       imacfb_fix.ywrapstep = 0;
-
-       /* request failure does not faze us, as vgacon probably has this
-        * region already (FIXME) */
-       request_region(0x3c0, 32, "imacfb");
-
-       info->fbops = &imacfb_ops;
-       info->var = imacfb_defined;
-       info->fix = imacfb_fix;
-       info->flags = FBINFO_FLAG_DEFAULT;
-
-       if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
-               err = -ENOMEM;
-               goto err_unmap;
-       }
-       if (register_framebuffer(info)<0) {
-               err = -EINVAL;
-               goto err_fb_dealoc;
-       }
-       printk(KERN_INFO "fb%d: %s frame buffer device\n",
-              info->node, info->fix.id);
-       return 0;
-
-err_fb_dealoc:
-       fb_dealloc_cmap(&info->cmap);
-err_unmap:
-       iounmap(info->screen_base);
-       framebuffer_release(info);
-err_release_mem:
-       release_mem_region(imacfb_fix.smem_start, size_total);
-       return err;
-}
-
-static struct platform_driver imacfb_driver = {
-       .probe  = imacfb_probe,
-       .driver = {
-               .name   = "imacfb",
-       },
-};
-
-static struct platform_device imacfb_device = {
-       .name   = "imacfb",
-};
-
-static int __init imacfb_init(void)
-{
-       int ret;
-       char *option = NULL;
-
-       if (!efi_enabled)
-               return -ENODEV;
-       if (!dmi_check_system(dmi_system_table))
-               return -ENODEV;
-       if (model == M_UNKNOWN)
-               return -ENODEV;
-
-       if (fb_get_options("imacfb", &option))
-               return -ENODEV;
-
-       imacfb_setup(option);
-       ret = platform_driver_register(&imacfb_driver);
-
-       if (!ret) {
-               ret = platform_device_register(&imacfb_device);
-               if (ret)
-                       platform_driver_unregister(&imacfb_driver);
-       }
-       return ret;
-}
-module_init(imacfb_init);
-
-MODULE_LICENSE("GPL");
index 3325fbd68ab3b235a9ec370e59cd96314b414359..a50bea6148044bdf4fb08e1ce49c377fc2aa9939 100644 (file)
@@ -12,9 +12,9 @@
 #endif
 
 /*** Version/name ***/
-#define INTELFB_VERSION                        "0.9.5"
+#define INTELFB_VERSION                        "0.9.6"
 #define INTELFB_MODULE_NAME            "intelfb"
-#define SUPPORTED_CHIPSETS             "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
+#define SUPPORTED_CHIPSETS             "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
 
 
 /*** Debug/feature defines ***/
@@ -58,6 +58,7 @@
 #define PCI_DEVICE_ID_INTEL_915GM      0x2592
 #define PCI_DEVICE_ID_INTEL_945G       0x2772
 #define PCI_DEVICE_ID_INTEL_945GM      0x27A2
+#define PCI_DEVICE_ID_INTEL_945GME     0x27AE
 #define PCI_DEVICE_ID_INTEL_965G       0x29A2
 #define PCI_DEVICE_ID_INTEL_965GM      0x2A02
 
@@ -160,6 +161,7 @@ enum intel_chips {
        INTEL_915GM,
        INTEL_945G,
        INTEL_945GM,
+       INTEL_945GME,
        INTEL_965G,
        INTEL_965GM,
 };
@@ -363,6 +365,7 @@ struct intelfb_info {
                        ((dinfo)->chipset == INTEL_915GM) ||    \
                        ((dinfo)->chipset == INTEL_945G) ||     \
                        ((dinfo)->chipset == INTEL_945GM) ||    \
+                       ((dinfo)->chipset == INTEL_945GME) ||   \
                        ((dinfo)->chipset == INTEL_965G) ||     \
                        ((dinfo)->chipset == INTEL_965GM))
 
index fcf9fadbf5722d328f521af00aa8fe5675e16da0..5d896b81f4e040a32a0fb6a2710c56c170224274 100644 (file)
@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
                /* has some LVDS + tv-out */
        case INTEL_945G:
        case INTEL_945GM:
+       case INTEL_945GME:
        case INTEL_965G:
        case INTEL_965GM:
                /* SDVO ports have a single control bus - 2 devices */
index e44303f9bc524ea64e86bd00030ffbaa3110dd01..a09e236493576f7602366e66d57781616c5c3933 100644 (file)
@@ -2,7 +2,7 @@
  * intelfb
  *
  * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
- * 945G/945GM/965G/965GM integrated graphics chips.
+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
  *
  * Copyright Â© 2002, 2003 David Dawes <dawes@xfree86.org>
  *                   2004 Sylvain Meyer
  *
  *    04/2008 - Version 0.9.5
  *              Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
+ *
+ *    08/2008 - Version 0.9.6
+ *              Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
  */
 
 #include <linux/module.h>
@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
        { 0, }
@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
            (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
            (ent->device == PCI_DEVICE_ID_INTEL_945G)  ||
            (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
+           (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
            (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
            (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
 
index 8e6d6a4db0ad85a52d8fd8313fcaf7f9f6884d3b..8b26b27c2db6f5f6ed68853a1ed1f7118e9c7c4d 100644 (file)
@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
                dinfo->mobile = 1;
                dinfo->pll_index = PLLS_I9xx;
                return 0;
+       case PCI_DEVICE_ID_INTEL_945GME:
+               dinfo->name = "Intel(R) 945GME";
+               dinfo->chipset = INTEL_945GME;
+               dinfo->mobile = 1;
+               dinfo->pll_index = PLLS_I9xx;
+               return 0;
        case PCI_DEVICE_ID_INTEL_965G:
                dinfo->name = "Intel(R) 965G";
                dinfo->chipset = INTEL_965G;
@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
        case PCI_DEVICE_ID_INTEL_915GM:
        case PCI_DEVICE_ID_INTEL_945G:
        case PCI_DEVICE_ID_INTEL_945GM:
+       case PCI_DEVICE_ID_INTEL_945GME:
        case PCI_DEVICE_ID_INTEL_965G:
        case PCI_DEVICE_ID_INTEL_965GM:
                /* 915, 945 and 965 chipsets support a 256MB aperture.
index c02136202792fab1b97c8d9a6d3938db69c241cb..8e7a275df50c79a13c328785a2909d66aae7a0bb 100644 (file)
@@ -1453,6 +1453,13 @@ static struct board {
                MGA_G100,
                &vbG100,
                "MGA-G100 (AGP)"},
+       {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G200EV_PCI,        0xFF,
+               0,                      0,
+               DEVF_G200,
+               230000,
+               MGA_G200,
+               &vbG200,
+               "MGA-G200eV (PCI)"},
        {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G200_PCI,  0xFF,
                0,                      0,
                DEVF_G200,
@@ -2118,6 +2125,8 @@ static struct pci_device_id matroxfb_devices[] = {
                PCI_ANY_ID,     PCI_ANY_ID,     0, 0, 0},
        {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G100_AGP,
                PCI_ANY_ID,     PCI_ANY_ID,     0, 0, 0},
+       {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G200EV_PCI,
+               PCI_ANY_ID,     PCI_ANY_ID,     0, 0, 0},
        {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G200_PCI,
                PCI_ANY_ID,     PCI_ANY_ID,     0, 0, 0},
        {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G200_AGP,
index afeed0611e3e0896cc28e05d355a9fdad73a6d08..df1f757a6161cde2f7d189be4501567af96fd6f2 100644 (file)
@@ -188,7 +188,7 @@ static int __devinit load_waveform(u8 *mem, size_t size, int m, int t,
                epd_frame_table[par->dt].wfm_size = user_wfm_size;
 
        if (size != epd_frame_table[par->dt].wfm_size) {
-               dev_err(dev, "Error: unexpected size %d != %d\n", size,
+               dev_err(dev, "Error: unexpected size %Zd != %d\n", size,
                                        epd_frame_table[par->dt].wfm_size);
                return -EINVAL;
        }
index 25172b2a2a941e15fe684e9130293c019467981d..bfb802d26d5af7286a59364c15f50ca9f881e97e 100644 (file)
@@ -426,11 +426,11 @@ static void vgaHWProtect(int on)
 {
        unsigned char tmp;
 
+       tmp = vga_rseq(NULL, 0x01);
        if (on) {
                /*
                 * Turn off screen and disable sequencer.
                 */
-               tmp = vga_rseq(NULL, 0x01);
                vga_wseq(NULL, 0x00, 0x01);             /* Synchronous Reset */
                vga_wseq(NULL, 0x01, tmp | 0x20);       /* disable the display */
 
@@ -439,7 +439,6 @@ static void vgaHWProtect(int on)
                /*
                 * Reenable sequencer, then turn on screen.
                 */
-               tmp = vga_rseq(NULL, 0x01);
                vga_wseq(NULL, 0x01, tmp & ~0x20);      /* reenable display */
                vga_wseq(NULL, 0x00, 0x03);             /* clear synchronousreset */
 
@@ -558,14 +557,12 @@ neofb_open(struct fb_info *info, int user)
 {
        struct neofb_par *par = info->par;
 
-       mutex_lock(&par->open_lock);
        if (!par->ref_count) {
                memset(&par->state, 0, sizeof(struct vgastate));
                par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
                save_vga(&par->state);
        }
        par->ref_count++;
-       mutex_unlock(&par->open_lock);
 
        return 0;
 }
@@ -575,16 +572,13 @@ neofb_release(struct fb_info *info, int user)
 {
        struct neofb_par *par = info->par;
 
-       mutex_lock(&par->open_lock);
-       if (!par->ref_count) {
-               mutex_unlock(&par->open_lock);
+       if (!par->ref_count)
                return -EINVAL;
-       }
+
        if (par->ref_count == 1) {
                restore_vga(&par->state);
        }
        par->ref_count--;
-       mutex_unlock(&par->open_lock);
 
        return 0;
 }
@@ -648,10 +642,10 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        var->blue.msb_right = 0;
        var->transp.msb_right = 0;
 
+       var->transp.offset = 0;
+       var->transp.length = 0;
        switch (var->bits_per_pixel) {
        case 8:         /* PSEUDOCOLOUR, 256 */
-               var->transp.offset = 0;
-               var->transp.length = 0;
                var->red.offset = 0;
                var->red.length = 8;
                var->green.offset = 0;
@@ -661,8 +655,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                break;
 
        case 16:                /* DIRECTCOLOUR, 64k */
-               var->transp.offset = 0;
-               var->transp.length = 0;
                var->red.offset = 11;
                var->red.length = 5;
                var->green.offset = 5;
@@ -672,8 +664,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                break;
 
        case 24:                /* TRUECOLOUR, 16m */
-               var->transp.offset = 0;
-               var->transp.length = 0;
                var->red.offset = 16;
                var->red.length = 8;
                var->green.offset = 8;
@@ -704,8 +694,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        if (vramlen > 4 * 1024 * 1024)
                vramlen = 4 * 1024 * 1024;
 
-       if (var->yres_virtual < var->yres)
-               var->yres_virtual = var->yres;
        if (var->xres_virtual < var->xres)
                var->xres_virtual = var->xres;
 
@@ -722,8 +710,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
           if it was possible. We should return -EINVAL, but I disagree */
        if (var->yres_virtual < var->yres)
                var->yres = var->yres_virtual;
-       if (var->xres_virtual < var->xres)
-               var->xres = var->xres_virtual;
        if (var->xoffset + var->xres > var->xres_virtual)
                var->xoffset = var->xres_virtual - var->xres;
        if (var->yoffset + var->yres > var->yres_virtual)
@@ -1186,8 +1172,11 @@ static int neofb_set_par(struct fb_info *info)
        return 0;
 }
 
-static void neofb_update_start(struct fb_info *info,
-                              struct fb_var_screeninfo *var)
+/*
+ *    Pan or Wrap the Display
+ */
+static int neofb_pan_display(struct fb_var_screeninfo *var,
+                            struct fb_info *info)
 {
        struct neofb_par *par = info->par;
        struct vgastate *state = &par->state;
@@ -1216,35 +1205,7 @@ static void neofb_update_start(struct fb_info *info,
        vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
 
        neoLock(state);
-}
-
-/*
- *    Pan or Wrap the Display
- */
-static int neofb_pan_display(struct fb_var_screeninfo *var,
-                            struct fb_info *info)
-{
-       u_int y_bottom;
-
-       y_bottom = var->yoffset;
-
-       if (!(var->vmode & FB_VMODE_YWRAP))
-               y_bottom += var->yres;
 
-       if (var->xoffset > (var->xres_virtual - var->xres))
-               return -EINVAL;
-       if (y_bottom > info->var.yres_virtual)
-               return -EINVAL;
-
-       neofb_update_start(info, var);
-
-       info->var.xoffset = var->xoffset;
-       info->var.yoffset = var->yoffset;
-
-       if (var->vmode & FB_VMODE_YWRAP)
-               info->var.vmode |= FB_VMODE_YWRAP;
-       else
-               info->var.vmode &= ~FB_VMODE_YWRAP;
        return 0;
 }
 
@@ -1992,7 +1953,6 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
 
        info->fix.accel = id->driver_data;
 
-       mutex_init(&par->open_lock);
        par->pci_burst = !nopciburst;
        par->lcd_stretch = !nostretch;
        par->libretto = libretto;
index 6efcf89e7fbe9667e9f4722e91fd8dfeb0964bd3..dfb72f5e4c962ad35098fb07a65252b99be31941 100644 (file)
@@ -156,7 +156,7 @@ struct resmap {
 };
 
 static struct {
-       u32             base;
+       void __iomem    *base;
 
        struct omapfb_mem_desc  mem_desc;
        struct resmap           *res_map[DISPC_MEMTYPE_NUM];
@@ -212,9 +212,9 @@ static void enable_rfbi_mode(int enable)
        dispc_write_reg(DISPC_CONTROL, l);
 
        /* Set bypass mode in RFBI module */
-       l = __raw_readl(io_p2v(RFBI_CONTROL));
+       l = __raw_readl(IO_ADDRESS(RFBI_CONTROL));
        l |= enable ? 0 : (1 << 1);
-       __raw_writel(l, io_p2v(RFBI_CONTROL));
+       __raw_writel(l, IO_ADDRESS(RFBI_CONTROL));
 }
 
 static void set_lcd_data_lines(int data_lines)
@@ -1349,14 +1349,19 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
 
        memset(&dispc, 0, sizeof(dispc));
 
-       dispc.base = io_p2v(DISPC_BASE);
+       dispc.base = ioremap(DISPC_BASE, SZ_1K);
+       if (!dispc.base) {
+               dev_err(fbdev->dev, "can't ioremap DISPC\n");
+               return -ENOMEM;
+       }
+
        dispc.fbdev = fbdev;
        dispc.ext_mode = ext_mode;
 
        init_completion(&dispc.frame_done);
 
        if ((r = get_dss_clocks()) < 0)
-               return r;
+               goto fail0;
 
        enable_interface_clocks(1);
        enable_lcd_clocks(1);
@@ -1414,7 +1419,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
        }
 
        /* L3 firewall setting: enable access to OCM RAM */
-       __raw_writel(0x402000b0, io_p2v(0x680050a0));
+       __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));
 
        if ((r = alloc_palette_ram()) < 0)
                goto fail2;
@@ -1464,7 +1469,8 @@ fail1:
        enable_lcd_clocks(0);
        enable_interface_clocks(0);
        put_dss_clocks();
-
+fail0:
+       iounmap(dispc.base);
        return r;
 }
 
@@ -1481,6 +1487,7 @@ static void omap_dispc_cleanup(void)
        free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
        enable_interface_clocks(0);
        put_dss_clocks();
+       iounmap(dispc.base);
 }
 
 const struct lcd_ctrl omap2_int_ctrl = {
index eb1512b56ce86e3c0c54e4da0607d05750b40112..ef720a78f6d513155d38ae1cba4061c966d0d1fa 100644 (file)
@@ -40,4 +40,6 @@ extern void omap_dispc_enable_digit_out(int enable);
 extern int  omap_dispc_request_irq(void (*callback)(void *data), void *data);
 extern void omap_dispc_free_irq(void);
 
+extern const struct lcd_ctrl omap2_int_ctrl;
+
 #endif
index 88c19d424ef769f32f1fe9fa23996b7214f4e9ec..6ff56430341b862a21dbbbaec416b13f17e484a1 100644 (file)
@@ -47,7 +47,7 @@ static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
        return 0;
 }
 
-struct lcd_panel h4_panel = {
+static struct lcd_panel h4_panel = {
        .name           = "h4",
        .config         = OMAP_LCDC_PANEL_TFT,
 
@@ -91,7 +91,7 @@ static int h4_panel_resume(struct platform_device *pdev)
        return 0;
 }
 
-struct platform_driver h4_panel_driver = {
+static struct platform_driver h4_panel_driver = {
        .probe          = h4_panel_probe,
        .remove         = h4_panel_remove,
        .suspend        = h4_panel_suspend,
index 6a42c6a0cd9991466b1a77781873e05b3171fcd8..4c4f7ee6d733a66e739c6be1e9cd65ad370f8633 100644 (file)
@@ -32,43 +32,43 @@ static int innovator1610_panel_init(struct lcd_panel *panel,
 {
        int r = 0;
 
-       if (omap_request_gpio(14)) {
+       if (gpio_request(14, "lcd_en0")) {
                pr_err(MODULE_NAME ": can't request GPIO 14\n");
                r = -1;
                goto exit;
        }
-       if (omap_request_gpio(15)) {
+       if (gpio_request(15, "lcd_en1")) {
                pr_err(MODULE_NAME ": can't request GPIO 15\n");
-               omap_free_gpio(14);
+               gpio_free(14);
                r = -1;
                goto exit;
        }
        /* configure GPIO(14, 15) as outputs */
-       omap_set_gpio_direction(14, 0);
-       omap_set_gpio_direction(15, 0);
+       gpio_direction_output(14, 0);
+       gpio_direction_output(15, 0);
 exit:
        return r;
 }
 
 static void innovator1610_panel_cleanup(struct lcd_panel *panel)
 {
-       omap_free_gpio(15);
-       omap_free_gpio(14);
+       gpio_free(15);
+       gpio_free(14);
 }
 
 static int innovator1610_panel_enable(struct lcd_panel *panel)
 {
        /* set GPIO14 and GPIO15 high */
-       omap_set_gpio_dataout(14, 1);
-       omap_set_gpio_dataout(15, 1);
+       gpio_set_value(14, 1);
+       gpio_set_value(15, 1);
        return 0;
 }
 
 static void innovator1610_panel_disable(struct lcd_panel *panel)
 {
        /* set GPIO13, GPIO14 and GPIO15 low */
-       omap_set_gpio_dataout(14, 0);
-       omap_set_gpio_dataout(15, 0);
+       gpio_set_value(14, 0);
+       gpio_set_value(15, 0);
 }
 
 static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel)
index a4a725f427a487843b03cad5e45abbf4fd230004..379c96d36da5833377e5d5df97085662ed6b52f5 100644 (file)
@@ -29,6 +29,7 @@
 
 static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
 {
+       /* gpio2 was allocated in board init */
        return 0;
 }
 
@@ -47,11 +48,8 @@ static int osk_panel_enable(struct lcd_panel *panel)
        /* Set PWL level */
        omap_writeb(0xFF, OMAP_PWL_ENABLE);
 
-       /* configure GPIO2 as output */
-       omap_set_gpio_direction(2, 0);
-
-       /* set GPIO2 high */
-       omap_set_gpio_dataout(2, 1);
+       /* set GPIO2 high (lcd power enabled) */
+       gpio_set_value(2, 1);
 
        return 0;
 }
@@ -65,7 +63,7 @@ static void osk_panel_disable(struct lcd_panel *panel)
        omap_writeb(0x00, OMAP_PWL_CLK_ENABLE);
 
        /* set GPIO2 low */
-       omap_set_gpio_dataout(2, 0);
+       gpio_set_value(2, 0);
 }
 
 static unsigned long osk_panel_get_caps(struct lcd_panel *panel)
index caa6a896cb8b7d84912dceb6a45b7e3871f3c588..e55de201b8ff4508e6de02ae29c970acf9cffb2f 100644 (file)
@@ -81,21 +81,21 @@ static void epson_sendbyte(int flag, unsigned char byte)
        int i, shifter = 0x80;
 
        if (!flag)
-               omap_set_gpio_dataout(_A_LCD_SSC_A0, 0);
+               gpio_set_value(_A_LCD_SSC_A0, 0);
        mdelay(2);
-       omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
+       gpio_set_value(A_LCD_SSC_RD, 1);
 
-       omap_set_gpio_dataout(A_LCD_SSC_SD, flag);
+       gpio_set_value(A_LCD_SSC_SD, flag);
 
        OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
        OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
        for (i = 0; i < 8; i++) {
                OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
-               omap_set_gpio_dataout(A_LCD_SSC_SD, shifter & byte);
+               gpio_set_value(A_LCD_SSC_SD, shifter & byte);
                OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
                shifter >>= 1;
        }
-       omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
+       gpio_set_value(_A_LCD_SSC_A0, 1);
 }
 
 static void init_system(void)
@@ -107,25 +107,18 @@ static void init_system(void)
 static void setup_GPIO(void)
 {
        /* new wave */
-       omap_request_gpio(A_LCD_SSC_RD);
-       omap_request_gpio(A_LCD_SSC_SD);
-       omap_request_gpio(_A_LCD_RESET);
-       omap_request_gpio(_A_LCD_SSC_CS);
-       omap_request_gpio(_A_LCD_SSC_A0);
-
-       /* set all GPIOs to output */
-       omap_set_gpio_direction(A_LCD_SSC_RD, 0);
-       omap_set_gpio_direction(A_LCD_SSC_SD, 0);
-       omap_set_gpio_direction(_A_LCD_RESET, 0);
-       omap_set_gpio_direction(_A_LCD_SSC_CS, 0);
-       omap_set_gpio_direction(_A_LCD_SSC_A0, 0);
-
-       /* set GPIO data */
-       omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
-       omap_set_gpio_dataout(A_LCD_SSC_SD, 0);
-       omap_set_gpio_dataout(_A_LCD_RESET, 0);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
+       gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd");
+       gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd");
+       gpio_request(_A_LCD_RESET, "lcd_reset");
+       gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs");
+       gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0");
+
+       /* set GPIOs to output, with initial data */
+       gpio_direction_output(A_LCD_SSC_RD, 1);
+       gpio_direction_output(A_LCD_SSC_SD, 0);
+       gpio_direction_output(_A_LCD_RESET, 0);
+       gpio_direction_output(_A_LCD_SSC_CS, 1);
+       gpio_direction_output(_A_LCD_SSC_A0, 1);
 }
 
 static void display_init(void)
@@ -139,61 +132,61 @@ static void display_init(void)
        mdelay(2);
 
        /* reset LCD */
-       omap_set_gpio_dataout(A_LCD_SSC_SD, 1);
+       gpio_set_value(A_LCD_SSC_SD, 1);
        epson_sendbyte(0, 0x25);
 
-       omap_set_gpio_dataout(_A_LCD_RESET, 0);
+       gpio_set_value(_A_LCD_RESET, 0);
        mdelay(10);
-       omap_set_gpio_dataout(_A_LCD_RESET, 1);
+       gpio_set_value(_A_LCD_RESET, 1);
 
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
        mdelay(2);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD, phase 1 */
        epson_sendbyte(0, 0xCA);
        for (i = 0; i < 10; i++)
                epson_sendbyte(1, INIT_1[i]);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 2 */
        epson_sendbyte(0, 0xCB);
        for (i = 0; i < 125; i++)
                epson_sendbyte(1, INIT_2[i]);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 2a */
        epson_sendbyte(0, 0xCC);
        for (i = 0; i < 14; i++)
                epson_sendbyte(1, INIT_3[i]);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 3 */
        epson_sendbyte(0, 0xBC);
        epson_sendbyte(1, 0x08);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 4 */
        epson_sendbyte(0, 0x07);
        epson_sendbyte(1, 0x05);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 5 */
        epson_sendbyte(0, 0x94);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 6 */
        epson_sendbyte(0, 0xC6);
        epson_sendbyte(1, 0x80);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
        mdelay(100); /* used to be 1000 */
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 7 */
        epson_sendbyte(0, 0x16);
@@ -201,8 +194,8 @@ static void display_init(void)
        epson_sendbyte(1, 0x00);
        epson_sendbyte(1, 0xB1);
        epson_sendbyte(1, 0x00);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 8 */
        epson_sendbyte(0, 0x76);
@@ -210,12 +203,12 @@ static void display_init(void)
        epson_sendbyte(1, 0x00);
        epson_sendbyte(1, 0xDB);
        epson_sendbyte(1, 0x00);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        /* init LCD phase 9 */
        epson_sendbyte(0, 0xAF);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
 }
 
 static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
@@ -231,18 +224,18 @@ static void sx1_panel_disable(struct lcd_panel *panel)
 {
        printk(KERN_INFO "SX1: LCD panel disable\n");
        sx1_setmmipower(0);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
 
        epson_sendbyte(0, 0x25);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        epson_sendbyte(0, 0xAE);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
        mdelay(100);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+       gpio_set_value(_A_LCD_SSC_CS, 0);
 
        epson_sendbyte(0, 0x95);
-       omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+       gpio_set_value(_A_LCD_SSC_CS, 1);
 }
 
 static int sx1_panel_enable(struct lcd_panel *panel)
index 83514f066712c4d3157b9c3c1c1b2a72d7b82d68..6e2ea7518761cb95b8161080d6adadc0ed2de792 100644 (file)
@@ -34,6 +34,8 @@
 
 #include <asm/mach-types.h>
 
+#include "lcdc.h"
+
 #define MODULE_NAME                    "lcdc"
 
 #define OMAP_LCDC_BASE                 0xfffec000
index adb731e5314a22e5702e98f389e81c33614c78dd..845222270db3f60b01ffdd7278f0c15ac3be2ac1 100644 (file)
@@ -4,4 +4,6 @@
 int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data);
 void omap_lcdc_free_dma_callback(void);
 
+extern const struct lcd_ctrl omap1_int_ctrl;
+
 #endif
index 51a138bd113c0a42a4d385bf0af2ab4e8b790ab6..5a5e407dc45f713cc9252f11efcf1ae2b113f2a3 100644 (file)
 #include <mach/dma.h>
 #include <mach/omapfb.h>
 
+#include "lcdc.h"
+#include "dispc.h"
+
 #define MODULE_NAME    "omapfb"
 
 static unsigned int    def_accel;
 static unsigned long   def_vram[OMAPFB_PLANE_NUM];
-static int             def_vram_cnt;
+static unsigned int    def_vram_cnt;
 static unsigned long   def_vxres;
 static unsigned long   def_vyres;
 static unsigned int    def_rotate;
@@ -84,12 +87,10 @@ static struct caps_table_struct color_caps[] = {
  * LCD panel
  * ---------------------------------------------------------------------------
  */
-extern struct lcd_ctrl omap1_int_ctrl;
-extern struct lcd_ctrl omap2_int_ctrl;
 extern struct lcd_ctrl hwa742_ctrl;
 extern struct lcd_ctrl blizzard_ctrl;
 
-static struct lcd_ctrl *ctrls[] = {
+static const struct lcd_ctrl *ctrls[] = {
 #ifdef CONFIG_ARCH_OMAP1
        &omap1_int_ctrl,
 #else
@@ -740,7 +741,7 @@ static int omapfb_update_win(struct fb_info *fbi,
        int ret;
 
        omapfb_rqueue_lock(plane->fbdev);
-       ret = omapfb_update_window_async(fbi, win, NULL, 0);
+       ret = omapfb_update_window_async(fbi, win, NULL, NULL);
        omapfb_rqueue_unlock(plane->fbdev);
 
        return ret;
@@ -768,7 +769,7 @@ static int omapfb_update_full_screen(struct fb_info *fbi)
        win.format = 0;
 
        omapfb_rqueue_lock(fbdev);
-       r = fbdev->ctrl->update_window(fbi, &win, NULL, 0);
+       r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL);
        omapfb_rqueue_unlock(fbdev);
 
        return r;
@@ -1047,7 +1048,7 @@ void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval)
                win.height = 2;
                win.out_width = 2;
                win.out_height = 2;
-               fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, 0);
+               fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL);
        }
        omapfb_rqueue_unlock(fbdev);
 }
index 4a6f13d3facf9d69ed984036d599248f5dfd328e..a13c8dcad2a8429c1a5da98f489a60b0da46ff51 100644 (file)
@@ -59,7 +59,7 @@
 #define DISPC_CONTROL          0x0040
 
 static struct {
-       u32             base;
+       void __iomem    *base;
        void            (*lcdc_callback)(void *data);
        void            *lcdc_callback_data;
        unsigned long   l4_khz;
@@ -518,7 +518,11 @@ static int rfbi_init(struct omapfb_device *fbdev)
        int r;
 
        rfbi.fbdev = fbdev;
-       rfbi.base = io_p2v(RFBI_BASE);
+       rfbi.base = ioremap(RFBI_BASE, SZ_1K);
+       if (!rfbi.base) {
+               dev_err(fbdev->dev, "can't ioremap RFBI\n");
+               return -ENOMEM;
+       }
 
        if ((r = rfbi_get_clocks()) < 0)
                return r;
@@ -566,6 +570,7 @@ static void rfbi_cleanup(void)
 {
        omap_dispc_free_irq();
        rfbi_put_clocks();
+       iounmap(rfbi.base);
 }
 
 const struct lcd_ctrl_extif omap2_ext_if = {
index 6359353c2c67feb92f0d004d2f93fbb1cce35e38..a7694622024925befb1f26692523937146dd3588 100644 (file)
@@ -574,7 +574,12 @@ static int sossi_init(struct omapfb_device *fbdev)
        struct clk *dpll1out_ck;
        int r;
 
-       sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE);
+       sossi.base = ioremap(OMAP_SOSSI_BASE, SZ_1K);
+       if (!sossi.base) {
+               dev_err(fbdev->dev, "can't ioremap SoSSI\n");
+               return -ENOMEM;
+       }
+
        sossi.fbdev = fbdev;
        spin_lock_init(&sossi.lock);
 
@@ -665,6 +670,7 @@ static void sossi_cleanup(void)
 {
        omap_lcdc_free_dma_callback();
        clk_put(sossi.fck);
+       iounmap(sossi.base);
 }
 
 struct lcd_ctrl_extif omap1_ext_if = {
index b829dc7c5edfeb4d9621599aa05d1c0dd296dfa7..a7b01d2724b5110ce4365fa35e8c32c05c6b385c 100644 (file)
 #define dbg(fmt, args...) do { } while (0)
 #endif
 
+static const int __devinitconst s1d13xxxfb_revisions[] = {
+       S1D13506_CHIP_REV,      /* Rev.4 on HP Jornada 7xx S1D13506 */
+       S1D13806_CHIP_REV,      /* Rev.7 on .. */
+};
+
 /*
  * Here we define the default struct fb_fix_screeninfo
  */
@@ -538,6 +543,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
        struct fb_info *info;
        struct s1d13xxxfb_pdata *pdata = NULL;
        int ret = 0;
+       int i;
        u8 revision;
 
        dbg("probe called: device is %p\n", pdev);
@@ -607,10 +613,19 @@ s1d13xxxfb_probe(struct platform_device *pdev)
                goto bail;
        }
 
-       revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE);
-       if ((revision >> 2) != S1D_CHIP_REV) {
-               printk(KERN_INFO PFX "chip not found: %i\n", (revision >> 2));
-               ret = -ENODEV;
+       revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
+
+       ret = -ENODEV;
+
+       for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {
+               if (revision == s1d13xxxfb_revisions[i])
+                       ret = 0;
+       }
+
+       if (!ret)
+               printk(KERN_INFO PFX "chip revision %i\n", revision);
+       else {
+               printk(KERN_INFO PFX "unknown chip revision %i\n", revision);
                goto bail;
        }
 
index 4599a4385bc9794337d87ad697b313e9421d8246..14bd3f3680b8e549d6662e4d5779b8b259886a05 100644 (file)
@@ -1195,57 +1195,58 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
                return -ENOMEM;
 
        default_par = info->par;
+       info->fix = tdfx_fix;
 
        /* Configure the default fb_fix_screeninfo first */
        switch (pdev->device) {
        case PCI_DEVICE_ID_3DFX_BANSHEE:
-               strcpy(tdfx_fix.id, "3Dfx Banshee");
+               strcpy(info->fix.id, "3Dfx Banshee");
                default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
                break;
        case PCI_DEVICE_ID_3DFX_VOODOO3:
-               strcpy(tdfx_fix.id, "3Dfx Voodoo3");
+               strcpy(info->fix.id, "3Dfx Voodoo3");
                default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
                break;
        case PCI_DEVICE_ID_3DFX_VOODOO5:
-               strcpy(tdfx_fix.id, "3Dfx Voodoo5");
+               strcpy(info->fix.id, "3Dfx Voodoo5");
                default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
                break;
        }
 
-       tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
-       tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
-       if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
+       info->fix.mmio_start = pci_resource_start(pdev, 0);
+       info->fix.mmio_len = pci_resource_len(pdev, 0);
+       if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len,
                                "tdfx regbase")) {
                printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
                goto out_err;
        }
 
        default_par->regbase_virt =
-               ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+               ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
        if (!default_par->regbase_virt) {
                printk(KERN_ERR "fb: Can't remap %s register area.\n",
-                               tdfx_fix.id);
+                               info->fix.id);
                goto out_err_regbase;
        }
 
-       tdfx_fix.smem_start = pci_resource_start(pdev, 1);
-       tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device);
-       if (!tdfx_fix.smem_len) {
-               printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id);
+       info->fix.smem_start = pci_resource_start(pdev, 1);
+       info->fix.smem_len = do_lfb_size(default_par, pdev->device);
+       if (!info->fix.smem_len) {
+               printk(KERN_ERR "fb: Can't count %s memory.\n", info->fix.id);
                goto out_err_regbase;
        }
 
-       if (!request_mem_region(tdfx_fix.smem_start,
+       if (!request_mem_region(info->fix.smem_start,
                                pci_resource_len(pdev, 1), "tdfx smem")) {
                printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
                goto out_err_regbase;
        }
 
-       info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
-                                           tdfx_fix.smem_len);
+       info->screen_base = ioremap_nocache(info->fix.smem_start,
+                                           info->fix.smem_len);
        if (!info->screen_base) {
                printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
-                               tdfx_fix.id);
+                               info->fix.id);
                goto out_err_screenbase;
        }
 
@@ -1257,20 +1258,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
                goto out_err_screenbase;
        }
 
-       printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id,
-                       tdfx_fix.smem_len >> 10);
+       printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id,
+                       info->fix.smem_len >> 10);
 
        default_par->mtrr_handle = -1;
        if (!nomtrr)
                default_par->mtrr_handle =
-                       mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len,
+                       mtrr_add(info->fix.smem_start, info->fix.smem_len,
                                 MTRR_TYPE_WRCOMB, 1);
 
-       tdfx_fix.ypanstep       = nopan ? 0 : 1;
-       tdfx_fix.ywrapstep      = nowrap ? 0 : 1;
+       info->fix.ypanstep      = nopan ? 0 : 1;
+       info->fix.ywrapstep     = nowrap ? 0 : 1;
 
        info->fbops             = &tdfxfb_ops;
-       info->fix               = tdfx_fix;
        info->pseudo_palette    = default_par->palette;
        info->flags             = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 #ifdef CONFIG_FB_3DFX_ACCEL
@@ -1323,14 +1323,14 @@ out_err_iobase:
 out_err_screenbase:
        if (info->screen_base)
                iounmap(info->screen_base);
-       release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
+       release_mem_region(info->fix.smem_start, pci_resource_len(pdev, 1));
 out_err_regbase:
        /*
         * Cleanup after anything that was remapped/allocated.
         */
        if (default_par->regbase_virt)
                iounmap(default_par->regbase_virt);
-       release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+       release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
 out_err:
        framebuffer_release(info);
        return -ENXIO;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
new file mode 100644 (file)
index 0000000..2a38001
--- /dev/null
@@ -0,0 +1,1050 @@
+/*
+ * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller
+ *
+ * Copyright(C) 2005-2006 Chris Humbert
+ * Copyright(C) 2005 Dirk Opfer
+ * Copytight(C) 2007,2008 Dmitry Baryshkov
+ *
+ * Based on:
+ *     drivers/video/w100fb.c
+ *     code written by Sharp/Lineo for 2.4 kernels
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+/* Why should fb driver call console functions? because acquire_console_sem() */
+#include <linux/console.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/tmio.h>
+#include <linux/uaccess.h>
+
+/*
+ * accelerator commands
+ */
+#define TMIOFB_ACC_CSADR(x)    (0x00000000 | ((x) & 0x001ffffe))
+#define TMIOFB_ACC_CHPIX(x)    (0x01000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_CVPIX(x)    (0x02000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PSADR(x)    (0x03000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_PHPIX(x)    (0x04000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PVPIX(x)    (0x05000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PHOFS(x)    (0x06000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PVOFS(x)    (0x07000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_POADR(x)    (0x08000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_RSTR(x)     (0x09000000 | ((x) & 0x000000ff))
+#define TMIOFB_ACC_TCLOR(x)    (0x0A000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_FILL(x)     (0x0B000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_DSADR(x)    (0x0C000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_SSADR(x)    (0x0D000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_DHPIX(x)    (0x0E000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_DVPIX(x)    (0x0F000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_SHPIX(x)    (0x10000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_SVPIX(x)    (0x11000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_LBINI(x)    (0x12000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_LBK2(x)     (0x13000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SHBINI(x)   (0x14000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SHBK2(x)    (0x15000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SVBINI(x)   (0x16000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SVBK2(x)    (0x17000000 | ((x) & 0x0000ffff))
+
+#define TMIOFB_ACC_CMGO                0x20000000
+#define TMIOFB_ACC_CMGO_CEND   0x00000001
+#define TMIOFB_ACC_CMGO_INT    0x00000002
+#define TMIOFB_ACC_CMGO_CMOD   0x00000010
+#define TMIOFB_ACC_CMGO_CDVRV  0x00000020
+#define TMIOFB_ACC_CMGO_CDHRV  0x00000040
+#define TMIOFB_ACC_CMGO_RUND   0x00008000
+#define TMIOFB_ACC_SCGO                0x21000000
+#define TMIOFB_ACC_SCGO_CEND   0x00000001
+#define TMIOFB_ACC_SCGO_INT    0x00000002
+#define TMIOFB_ACC_SCGO_ROP3   0x00000004
+#define TMIOFB_ACC_SCGO_TRNS   0x00000008
+#define TMIOFB_ACC_SCGO_DVRV   0x00000010
+#define TMIOFB_ACC_SCGO_DHRV   0x00000020
+#define TMIOFB_ACC_SCGO_SVRV   0x00000040
+#define TMIOFB_ACC_SCGO_SHRV   0x00000080
+#define TMIOFB_ACC_SCGO_DSTXY  0x00008000
+#define TMIOFB_ACC_SBGO                0x22000000
+#define TMIOFB_ACC_SBGO_CEND   0x00000001
+#define TMIOFB_ACC_SBGO_INT    0x00000002
+#define TMIOFB_ACC_SBGO_DVRV   0x00000010
+#define TMIOFB_ACC_SBGO_DHRV   0x00000020
+#define TMIOFB_ACC_SBGO_SVRV   0x00000040
+#define TMIOFB_ACC_SBGO_SHRV   0x00000080
+#define TMIOFB_ACC_SBGO_SBMD   0x00000100
+#define TMIOFB_ACC_FLGO                0x23000000
+#define TMIOFB_ACC_FLGO_CEND   0x00000001
+#define TMIOFB_ACC_FLGO_INT    0x00000002
+#define TMIOFB_ACC_FLGO_ROP3   0x00000004
+#define TMIOFB_ACC_LDGO                0x24000000
+#define TMIOFB_ACC_LDGO_CEND   0x00000001
+#define TMIOFB_ACC_LDGO_INT    0x00000002
+#define TMIOFB_ACC_LDGO_ROP3   0x00000004
+#define TMIOFB_ACC_LDGO_ENDPX  0x00000008
+#define TMIOFB_ACC_LDGO_LVRV   0x00000010
+#define TMIOFB_ACC_LDGO_LHRV   0x00000020
+#define TMIOFB_ACC_LDGO_LDMOD  0x00000040
+
+/* a FIFO is always allocated, even if acceleration is not used */
+#define TMIOFB_FIFO_SIZE       512
+
+/*
+ * LCD Host Controller Configuration Register
+ *
+ * This iomem area supports only 16-bit IO.
+ */
+#define CCR_CMD                        0x04 /* Command                         */
+#define CCR_REVID              0x08 /* Revision ID                     */
+#define CCR_BASEL              0x10 /* LCD Control Reg Base Addr Low   */
+#define CCR_BASEH              0x12 /* LCD Control Reg Base Addr High  */
+#define CCR_UGCC               0x40 /* Unified Gated Clock Control     */
+#define CCR_GCC                        0x42 /* Gated Clock Control             */
+#define CCR_USC                        0x50 /* Unified Software Clear          */
+#define CCR_VRAMRTC            0x60 /* VRAM Timing Control             */
+                               /* 0x61 VRAM Refresh Control            */
+#define CCR_VRAMSAC            0x62 /* VRAM Access Control             */
+                               /* 0x63 VRAM Status                     */
+#define CCR_VRAMBC             0x64 /* VRAM Block Control              */
+
+/*
+ * LCD Control Register
+ *
+ * This iomem area supports only 16-bit IO.
+ */
+#define LCR_UIS                        0x000 /* Unified Interrupt Status       */
+#define LCR_VHPN               0x008 /* VRAM Horizontal Pixel Number   */
+#define LCR_CFSAL              0x00a /* Command FIFO Start Address Low */
+#define LCR_CFSAH              0x00c /* Command FIFO Start Address High */
+#define LCR_CFS                        0x00e /* Command FIFO Size              */
+#define LCR_CFWS               0x010 /* Command FIFO Writeable Size    */
+#define LCR_BBIE               0x012 /* BitBLT Interrupt Enable        */
+#define LCR_BBISC              0x014 /* BitBLT Interrupt Status and Clear */
+#define LCR_CCS                        0x016 /* Command Count Status           */
+#define LCR_BBES               0x018 /* BitBLT Execution Status        */
+#define LCR_CMDL               0x01c /* Command Low                    */
+#define LCR_CMDH               0x01e /* Command High                   */
+#define LCR_CFC                        0x022 /* Command FIFO Clear             */
+#define LCR_CCIFC              0x024 /* CMOS Camera IF Control         */
+#define LCR_HWT                        0x026 /* Hardware Test                  */
+#define LCR_LCDCCRC            0x100 /* LCDC Clock and Reset Control   */
+#define LCR_LCDCC              0x102 /* LCDC Control                   */
+#define LCR_LCDCOPC            0x104 /* LCDC Output Pin Control        */
+#define LCR_LCDIS              0x108 /* LCD Interrupt Status           */
+#define LCR_LCDIM              0x10a /* LCD Interrupt Mask             */
+#define LCR_LCDIE              0x10c /* LCD Interrupt Enable           */
+#define LCR_GDSAL              0x122 /* Graphics Display Start Address Low */
+#define LCR_GDSAH              0x124 /* Graphics Display Start Address High */
+#define LCR_VHPCL              0x12a /* VRAM Horizontal Pixel Count Low */
+#define LCR_VHPCH              0x12c /* VRAM Horizontal Pixel Count High */
+#define LCR_GM                 0x12e /* Graphic Mode(VRAM access enable) */
+#define LCR_HT                 0x140 /* Horizontal Total               */
+#define LCR_HDS                        0x142 /* Horizontal Display Start       */
+#define LCR_HSS                        0x144 /* H-Sync Start                   */
+#define LCR_HSE                        0x146 /* H-Sync End                     */
+#define LCR_HNP                        0x14c /* Horizontal Number of Pixels    */
+#define LCR_VT                 0x150 /* Vertical Total                 */
+#define LCR_VDS                        0x152 /* Vertical Display Start         */
+#define LCR_VSS                        0x154 /* V-Sync Start                   */
+#define LCR_VSE                        0x156 /* V-Sync End                     */
+#define LCR_CDLN               0x160 /* Current Display Line Number    */
+#define LCR_ILN                        0x162 /* Interrupt Line Number          */
+#define LCR_SP                 0x164 /* Sync Polarity                  */
+#define LCR_MISC               0x166 /* MISC(RGB565 mode)              */
+#define LCR_VIHSS              0x16a /* Video Interface H-Sync Start   */
+#define LCR_VIVS               0x16c /* Video Interface Vertical Start */
+#define LCR_VIVE               0x16e /* Video Interface Vertical End   */
+#define LCR_VIVSS              0x170 /* Video Interface V-Sync Start   */
+#define LCR_VCCIS              0x17e /* Video / CMOS Camera Interface Select */
+#define LCR_VIDWSAL            0x180 /* VI Data Write Start Address Low */
+#define LCR_VIDWSAH            0x182 /* VI Data Write Start Address High */
+#define LCR_VIDRSAL            0x184 /* VI Data Read Start Address Low */
+#define LCR_VIDRSAH            0x186 /* VI Data Read Start Address High */
+#define LCR_VIPDDST            0x188 /* VI Picture Data Display Start Timing */
+#define LCR_VIPDDET            0x186 /* VI Picture Data Display End Timing */
+#define LCR_VIE                        0x18c /* Video Interface Enable         */
+#define LCR_VCS                        0x18e /* Video/Camera Select            */
+#define LCR_VPHWC              0x194 /* Video Picture Horizontal Wait Count */
+#define LCR_VPHS               0x196 /* Video Picture Horizontal Size  */
+#define LCR_VPVWC              0x198 /* Video Picture Vertical Wait Count */
+#define LCR_VPVS               0x19a /* Video Picture Vertical Size    */
+#define LCR_PLHPIX             0x1a0 /* PLHPIX                         */
+#define LCR_XS                 0x1a2 /* XStart                         */
+#define LCR_XCKHW              0x1a4 /* XCK High Width                 */
+#define LCR_STHS               0x1a8 /* STH Start                      */
+#define LCR_VT2                        0x1aa /* Vertical Total                 */
+#define LCR_YCKSW              0x1ac /* YCK Start Wait                 */
+#define LCR_YSTS               0x1ae /* YST Start                      */
+#define LCR_PPOLS              0x1b0 /* #PPOL Start                    */
+#define LCR_PRECW              0x1b2 /* PREC Width                     */
+#define LCR_VCLKHW             0x1b4 /* VCLK High Width                */
+#define LCR_OC                 0x1b6 /* Output Control                 */
+
+static char *mode_option __devinitdata;
+
+struct tmiofb_par {
+       u32                             pseudo_palette[16];
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+       wait_queue_head_t               wait_acc;
+       bool                            use_polling;
+#endif
+
+       void __iomem                    *ccr;
+       void __iomem                    *lcr;
+};
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * reasons for an interrupt:
+ *     uis     bbisc   lcdis
+ *     0100    0001    accelerator command completed
+ *     2000    0001    vsync start
+ *     2000    0002    display start
+ *     2000    0004    line number match(0x1ff mask???)
+ */
+static irqreturn_t tmiofb_irq(int irq, void *__info)
+{
+       struct fb_info *info = __info;
+       struct tmiofb_par *par = info->par;
+       unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC);
+
+
+       /*
+        * We were in polling mode and now we got correct irq.
+        * Switch back to IRQ-based sync of command FIFO
+        */
+       if (unlikely(par->use_polling && irq != -1)) {
+               printk(KERN_INFO "tmiofb: switching to waitq\n");
+               par->use_polling = false;
+       }
+
+       tmio_iowrite16(bbisc, par->lcr + LCR_BBISC);
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+       if (bbisc & 1)
+               wake_up(&par->wait_acc);
+#endif
+
+       return IRQ_HANDLED;
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+
+/*
+ * Turns off the LCD controller and LCD host controller.
+ */
+static int tmiofb_hw_stop(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct tmio_fb_data *data = cell->driver_data;
+       struct fb_info *info = platform_get_drvdata(dev);
+       struct tmiofb_par *par = info->par;
+
+       tmio_iowrite16(0, par->ccr + CCR_UGCC);
+       tmio_iowrite16(0, par->lcr + LCR_GM);
+       data->lcd_set_power(dev, 0);
+       tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
+
+       return 0;
+}
+
+/*
+ * Initializes the LCD host controller.
+ */
+static int tmiofb_hw_init(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct fb_info *info = platform_get_drvdata(dev);
+       struct tmiofb_par *par = info->par;
+       const struct resource *nlcr = &cell->resources[0];
+       const struct resource *vram = &cell->resources[2];
+       unsigned long base;
+
+       if (nlcr == NULL || vram == NULL)
+               return -EINVAL;
+
+       base = nlcr->start;
+
+       tmio_iowrite16(0x003a, par->ccr + CCR_UGCC);
+       tmio_iowrite16(0x003a, par->ccr + CCR_GCC);
+       tmio_iowrite16(0x3f00, par->ccr + CCR_USC);
+
+       msleep(2); /* wait for device to settle */
+
+       tmio_iowrite16(0x0000, par->ccr + CCR_USC);
+       tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH);
+       tmio_iowrite16(base, par->ccr + CCR_BASEL);
+       tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */
+       tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */
+       tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */
+       tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC);
+       msleep(2); /* wait for device to settle */
+       tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC);
+
+       base = vram->start + info->screen_size;
+       tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH);
+       tmio_iowrite16(base, par->lcr + LCR_CFSAL);
+       tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS);
+       tmio_iowrite16(1, par->lcr + LCR_CFC);
+       tmio_iowrite16(1, par->lcr + LCR_BBIE);
+       tmio_iowrite16(0, par->lcr + LCR_CFWS);
+
+       return 0;
+}
+
+/*
+ * Sets the LCD controller's output resolution and pixel clock
+ */
+static void tmiofb_hw_mode(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct tmio_fb_data *data = cell->driver_data;
+       struct fb_info *info = platform_get_drvdata(dev);
+       struct fb_videomode *mode = info->mode;
+       struct tmiofb_par *par = info->par;
+       unsigned int i;
+
+       tmio_iowrite16(0, par->lcr + LCR_GM);
+       data->lcd_set_power(dev, 0);
+       tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
+       data->lcd_mode(dev, mode);
+       data->lcd_set_power(dev, 1);
+
+       tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN);
+       tmio_iowrite16(0, par->lcr + LCR_GDSAH);
+       tmio_iowrite16(0, par->lcr + LCR_GDSAL);
+       tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH);
+       tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL);
+       tmio_iowrite16(i = 0, par->lcr + LCR_HSS);
+       tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE);
+       tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS);
+       tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT);
+       tmio_iowrite16(mode->xres, par->lcr + LCR_HNP);
+       tmio_iowrite16(i = 0, par->lcr + LCR_VSS);
+       tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE);
+       tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS);
+       tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN);
+       tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT);
+       tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */
+       tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */
+       tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC);
+       tmio_iowrite16(3, par->lcr + LCR_SP);  /* sync polarity */
+
+       tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
+       msleep(5); /* wait for device to settle */
+       tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */
+       msleep(5); /* wait for device to settle */
+       tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/
+       tmio_iowrite16(0xfffa, par->lcr + LCR_VCS);
+}
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+static int __must_check
+tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
+{
+       struct tmiofb_par *par = info->par;
+       /*
+        * This code can be called whith interrupts disabled.
+        * So instead of relaying on irq to trigger the event,
+        * poll the state till the necessary command is executed.
+        */
+       if (irqs_disabled() || par->use_polling) {
+               int i = 0;
+               while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) {
+                       udelay(1);
+                       i++;
+                       if (i > 10000) {
+                               pr_err("tmiofb: timeout waiting for %d\n",
+                                               ccs);
+                               return -ETIMEDOUT;
+                       }
+                       tmiofb_irq(-1, info);
+               }
+       } else {
+               if (!wait_event_interruptible_timeout(par->wait_acc,
+                               tmio_ioread16(par->lcr + LCR_CCS) <= ccs,
+                               1000)) {
+                       pr_err("tmiofb: timeout waiting for %d\n", ccs);
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Writes an accelerator command to the accelerator's FIFO.
+ */
+static int
+tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count)
+{
+       struct tmiofb_par *par = info->par;
+       int ret;
+
+       ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count);
+       if (ret)
+               return ret;
+
+       for (; count; count--, cmd++) {
+               tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH);
+               tmio_iowrite16(*cmd, par->lcr + LCR_CMDL);
+       }
+
+       return ret;
+}
+
+/*
+ * Wait for the accelerator to finish its operations before writing
+ * to the framebuffer for consistent display output.
+ */
+static int tmiofb_sync(struct fb_info *fbi)
+{
+       struct tmiofb_par *par = fbi->par;
+
+       int ret;
+       int i = 0;
+
+       ret = tmiofb_acc_wait(fbi, 0);
+
+       while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */
+               udelay(1);
+               i++ ;
+               if (i > 10000) {
+                       printk(KERN_ERR "timeout waiting for blit to end!\n");
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return ret;
+}
+
+static void
+tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect)
+{
+       const u32 cmd[] = {
+               TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2),
+               TMIOFB_ACC_DHPIX(rect->width - 1),
+               TMIOFB_ACC_DVPIX(rect->height - 1),
+               TMIOFB_ACC_FILL(rect->color),
+               TMIOFB_ACC_FLGO,
+       };
+
+       if (fbi->state != FBINFO_STATE_RUNNING ||
+           fbi->flags & FBINFO_HWACCEL_DISABLED) {
+               cfb_fillrect(fbi, rect);
+               return;
+       }
+
+       tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
+}
+
+static void
+tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area)
+{
+       const u32 cmd[] = {
+               TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2),
+               TMIOFB_ACC_DHPIX(area->width - 1),
+               TMIOFB_ACC_DVPIX(area->height - 1),
+               TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2),
+               TMIOFB_ACC_SCGO,
+       };
+
+       if (fbi->state != FBINFO_STATE_RUNNING ||
+           fbi->flags & FBINFO_HWACCEL_DISABLED) {
+               cfb_copyarea(fbi, area);
+               return;
+       }
+
+       tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
+}
+#endif
+
+static void tmiofb_clearscreen(struct fb_info *info)
+{
+       const struct fb_fillrect rect = {
+               .dx     = 0,
+               .dy     = 0,
+               .width  = info->mode->xres,
+               .height = info->mode->yres,
+               .color  = 0,
+               .rop    = ROP_COPY,
+       };
+
+       info->fbops->fb_fillrect(info, &rect);
+}
+
+static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank)
+{
+       struct tmiofb_par *par = fbi->par;
+       struct fb_videomode *mode = fbi->mode;
+       unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN);
+       unsigned int vds = mode->vsync_len + mode->upper_margin;
+
+       vblank->vcount = vcount;
+       vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT
+                                               | FB_VBLANK_HAVE_VSYNC;
+
+       if (vcount < mode->vsync_len)
+               vblank->flags |= FB_VBLANK_VSYNCING;
+
+       if (vcount < vds || vcount > vds + mode->yres)
+               vblank->flags |= FB_VBLANK_VBLANKING;
+
+       return 0;
+}
+
+
+static int tmiofb_ioctl(struct fb_info *fbi,
+               unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case FBIOGET_VBLANK: {
+               struct fb_vblank vblank = {0};
+               void __user *argp = (void __user *) arg;
+
+               tmiofb_vblank(fbi, &vblank);
+               if (copy_to_user(argp, &vblank, sizeof vblank))
+                       return -EFAULT;
+               return 0;
+       }
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+       case FBIO_TMIO_ACC_SYNC:
+               tmiofb_sync(fbi);
+               return 0;
+
+       case FBIO_TMIO_ACC_WRITE: {
+               u32 __user *argp = (void __user *) arg;
+               u32 len;
+               u32 acc[16];
+
+               if (get_user(len, argp))
+                       return -EFAULT;
+               if (len > ARRAY_SIZE(acc))
+                       return -EINVAL;
+               if (copy_from_user(acc, argp + 1, sizeof(u32) * len))
+                       return -EFAULT;
+
+               return tmiofb_acc_write(fbi, acc, len);
+       }
+#endif
+       }
+
+       return -ENOTTY;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Select the smallest mode that allows the desired resolution to be
+ * displayed.  If desired, the x and y parameters can be rounded up to
+ * match the selected mode.
+ */
+static struct fb_videomode *
+tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
+{
+       struct mfd_cell *cell =
+               info->device->platform_data;
+       struct tmio_fb_data *data = cell->driver_data;
+       struct fb_videomode *best = NULL;
+       int i;
+
+       for (i = 0; i < data->num_modes; i++) {
+               struct fb_videomode *mode = data->modes + i;
+
+               if (mode->xres >= var->xres && mode->yres >= var->yres
+                               && (!best || (mode->xres < best->xres
+                                          && mode->yres < best->yres)))
+                       best = mode;
+       }
+
+       return best;
+}
+
+static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+
+       struct fb_videomode *mode;
+       struct mfd_cell *cell =
+               info->device->platform_data;
+       struct tmio_fb_data *data = cell->driver_data;
+
+       mode = tmiofb_find_mode(info, var);
+       if (!mode || var->bits_per_pixel > 16)
+               return -EINVAL;
+
+       fb_videomode_to_var(var, mode);
+
+       var->xres_virtual = mode->xres;
+       var->yres_virtual = info->screen_size / (mode->xres * 2);
+
+       if (var->yres_virtual < var->yres)
+               return -EINVAL;
+
+       var->xoffset = 0;
+       var->yoffset = 0;
+       var->bits_per_pixel = 16;
+       var->grayscale = 0;
+       var->red.offset = 11;
+       var->red.length = 5;
+       var->green.offset = 5;
+       var->green.length = 6;
+       var->blue.offset = 0;
+       var->blue.length = 5;
+       var->transp.offset = 0;
+       var->transp.length = 0;
+       var->nonstd = 0;
+       var->height = data->height; /* mm */
+       var->width = data->width; /* mm */
+       var->rotate = 0;
+       return 0;
+}
+
+static int tmiofb_set_par(struct fb_info *info)
+{
+       struct fb_var_screeninfo *var = &info->var;
+       struct fb_videomode *mode;
+
+       mode = tmiofb_find_mode(info, var);
+       if (!mode)
+               return -EINVAL;
+
+       info->mode = mode;
+       info->fix.line_length = info->mode->xres *
+                       var->bits_per_pixel / 8;
+
+       tmiofb_hw_mode(to_platform_device(info->device));
+       tmiofb_clearscreen(info);
+       return 0;
+}
+
+static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
+                          unsigned blue, unsigned transp,
+                          struct fb_info *info)
+{
+       struct tmiofb_par *par = info->par;
+
+       if (regno < ARRAY_SIZE(par->pseudo_palette)) {
+               par->pseudo_palette[regno] =
+                       ((red & 0xf800)) |
+                       ((green & 0xfc00) >>  5) |
+                       ((blue & 0xf800) >> 11);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int tmiofb_blank(int blank, struct fb_info *info)
+{
+       /*
+        * everything is done in lcd/bl drivers.
+        * this is purely to make sysfs happy and work.
+        */
+       return 0;
+}
+
+static struct fb_ops tmiofb_ops = {
+       .owner          = THIS_MODULE,
+
+       .fb_ioctl       = tmiofb_ioctl,
+       .fb_check_var   = tmiofb_check_var,
+       .fb_set_par     = tmiofb_set_par,
+       .fb_setcolreg   = tmiofb_setcolreg,
+       .fb_blank       = tmiofb_blank,
+       .fb_imageblit   = cfb_imageblit,
+#ifdef CONFIG_FB_TMIO_ACCELL
+       .fb_sync        = tmiofb_sync,
+       .fb_fillrect    = tmiofb_fillrect,
+       .fb_copyarea    = tmiofb_copyarea,
+#else
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+#endif
+};
+
+/*--------------------------------------------------------------------------*/
+
+static int __devinit tmiofb_probe(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct tmio_fb_data *data = cell->driver_data;
+       struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
+       int irq = platform_get_irq(dev, 0);
+       struct fb_info *info;
+       struct tmiofb_par *par;
+       int retval;
+
+       /*
+        * This is the only way ATM to disable the fb
+        */
+       if (data == NULL) {
+               dev_err(&dev->dev, "NULL platform data!\n");
+               return -EINVAL;
+       }
+
+       info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
+
+       if (!info)
+               return -ENOMEM;
+
+       par = info->par;
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+       init_waitqueue_head(&par->wait_acc);
+
+       par->use_polling = true;
+
+       info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
+                       | FBINFO_HWACCEL_FILLRECT;
+#else
+       info->flags = FBINFO_DEFAULT;
+#endif
+
+       info->fbops = &tmiofb_ops;
+
+       strcpy(info->fix.id, "tmio-fb");
+       info->fix.smem_start = vram->start;
+       info->fix.smem_len = resource_size(vram);
+       info->fix.type = FB_TYPE_PACKED_PIXELS;
+       info->fix.visual = FB_VISUAL_TRUECOLOR;
+       info->fix.mmio_start = lcr->start;
+       info->fix.mmio_len = resource_size(lcr);
+       info->fix.accel = FB_ACCEL_NONE;
+       info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
+       info->pseudo_palette = par->pseudo_palette;
+
+       par->ccr = ioremap(ccr->start, resource_size(ccr));
+       if (!par->ccr) {
+               retval = -ENOMEM;
+               goto err_ioremap_ccr;
+       }
+
+       par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
+       if (!par->lcr) {
+               retval = -ENOMEM;
+               goto err_ioremap_lcr;
+       }
+
+       info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+       if (!info->screen_base) {
+               retval = -ENOMEM;
+               goto err_ioremap_vram;
+       }
+
+       retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
+                                       dev->dev.bus_id, info);
+
+       if (retval)
+               goto err_request_irq;
+
+       platform_set_drvdata(dev, info);
+
+       retval = fb_find_mode(&info->var, info, mode_option,
+                       data->modes, data->num_modes,
+                       data->modes, 16);
+       if (!retval) {
+               retval = -EINVAL;
+               goto err_find_mode;
+       }
+
+       if (cell->enable) {
+               retval = cell->enable(dev);
+               if (retval)
+                       goto err_enable;
+       }
+
+       retval = tmiofb_hw_init(dev);
+       if (retval)
+               goto err_hw_init;
+
+       fb_videomode_to_modelist(data->modes, data->num_modes,
+                                &info->modelist);
+
+       retval = register_framebuffer(info);
+       if (retval < 0)
+               goto err_register_framebuffer;
+
+       printk(KERN_INFO "fb%d: %s frame buffer device\n",
+                               info->node, info->fix.id);
+
+       return 0;
+
+err_register_framebuffer:
+/*err_set_par:*/
+       tmiofb_hw_stop(dev);
+err_hw_init:
+       if (cell->disable)
+               cell->disable(dev);
+err_enable:
+err_find_mode:
+       platform_set_drvdata(dev, NULL);
+       free_irq(irq, info);
+err_request_irq:
+       iounmap(info->screen_base);
+err_ioremap_vram:
+       iounmap(par->lcr);
+err_ioremap_lcr:
+       iounmap(par->ccr);
+err_ioremap_ccr:
+       framebuffer_release(info);
+       return retval;
+}
+
+static int __devexit tmiofb_remove(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct fb_info *info = platform_get_drvdata(dev);
+       int irq = platform_get_irq(dev, 0);
+       struct tmiofb_par *par;
+
+       if (info) {
+               par = info->par;
+               unregister_framebuffer(info);
+
+               tmiofb_hw_stop(dev);
+
+               if (cell->disable)
+                       cell->disable(dev);
+
+               platform_set_drvdata(dev, NULL);
+
+               free_irq(irq, info);
+
+               iounmap(info->screen_base);
+               iounmap(par->lcr);
+               iounmap(par->ccr);
+
+               framebuffer_release(info);
+       }
+
+       return 0;
+}
+
+#ifdef DEBUG
+static void tmiofb_dump_regs(struct platform_device *dev)
+{
+       struct fb_info *info = platform_get_drvdata(dev);
+       struct tmiofb_par *par = info->par;
+
+       printk(KERN_DEBUG "lhccr:\n");
+#define CCR_PR(n)      printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
+               tmio_ioread16(par->ccr + CCR_ ## n));
+       CCR_PR(CMD);
+       CCR_PR(REVID);
+       CCR_PR(BASEL);
+       CCR_PR(BASEH);
+       CCR_PR(UGCC);
+       CCR_PR(GCC);
+       CCR_PR(USC);
+       CCR_PR(VRAMRTC);
+       CCR_PR(VRAMSAC);
+       CCR_PR(VRAMBC);
+#undef CCR_PR
+
+       printk(KERN_DEBUG "lcr: \n");
+#define LCR_PR(n)      printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
+               tmio_ioread16(par->lcr + LCR_ ## n));
+       LCR_PR(UIS);
+       LCR_PR(VHPN);
+       LCR_PR(CFSAL);
+       LCR_PR(CFSAH);
+       LCR_PR(CFS);
+       LCR_PR(CFWS);
+       LCR_PR(BBIE);
+       LCR_PR(BBISC);
+       LCR_PR(CCS);
+       LCR_PR(BBES);
+       LCR_PR(CMDL);
+       LCR_PR(CMDH);
+       LCR_PR(CFC);
+       LCR_PR(CCIFC);
+       LCR_PR(HWT);
+       LCR_PR(LCDCCRC);
+       LCR_PR(LCDCC);
+       LCR_PR(LCDCOPC);
+       LCR_PR(LCDIS);
+       LCR_PR(LCDIM);
+       LCR_PR(LCDIE);
+       LCR_PR(GDSAL);
+       LCR_PR(GDSAH);
+       LCR_PR(VHPCL);
+       LCR_PR(VHPCH);
+       LCR_PR(GM);
+       LCR_PR(HT);
+       LCR_PR(HDS);
+       LCR_PR(HSS);
+       LCR_PR(HSE);
+       LCR_PR(HNP);
+       LCR_PR(VT);
+       LCR_PR(VDS);
+       LCR_PR(VSS);
+       LCR_PR(VSE);
+       LCR_PR(CDLN);
+       LCR_PR(ILN);
+       LCR_PR(SP);
+       LCR_PR(MISC);
+       LCR_PR(VIHSS);
+       LCR_PR(VIVS);
+       LCR_PR(VIVE);
+       LCR_PR(VIVSS);
+       LCR_PR(VCCIS);
+       LCR_PR(VIDWSAL);
+       LCR_PR(VIDWSAH);
+       LCR_PR(VIDRSAL);
+       LCR_PR(VIDRSAH);
+       LCR_PR(VIPDDST);
+       LCR_PR(VIPDDET);
+       LCR_PR(VIE);
+       LCR_PR(VCS);
+       LCR_PR(VPHWC);
+       LCR_PR(VPHS);
+       LCR_PR(VPVWC);
+       LCR_PR(VPVS);
+       LCR_PR(PLHPIX);
+       LCR_PR(XS);
+       LCR_PR(XCKHW);
+       LCR_PR(STHS);
+       LCR_PR(VT2);
+       LCR_PR(YCKSW);
+       LCR_PR(YSTS);
+       LCR_PR(PPOLS);
+       LCR_PR(PRECW);
+       LCR_PR(VCLKHW);
+       LCR_PR(OC);
+#undef LCR_PR
+}
+#endif
+
+#ifdef CONFIG_PM
+static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
+{
+       struct fb_info *info = platform_get_drvdata(dev);
+       struct tmiofb_par *par = info->par;
+       struct mfd_cell *cell = dev->dev.platform_data;
+       int retval = 0;
+
+       acquire_console_sem();
+
+       fb_set_suspend(info, 1);
+
+       if (info->fbops->fb_sync)
+               info->fbops->fb_sync(info);
+
+
+       /*
+        * The fb should be usable even if interrupts are disabled (and they are
+        * during suspend/resume). Switch temporary to forced polling.
+        */
+       printk(KERN_INFO "tmiofb: switching to polling\n");
+       par->use_polling = true;
+       tmiofb_hw_stop(dev);
+
+       if (cell->suspend)
+               retval = cell->suspend(dev);
+
+       release_console_sem();
+
+       return retval;
+}
+
+static int tmiofb_resume(struct platform_device *dev)
+{
+       struct fb_info *info = platform_get_drvdata(dev);
+       struct mfd_cell *cell = dev->dev.platform_data;
+       int retval;
+
+       acquire_console_sem();
+
+       if (cell->resume) {
+               retval = cell->resume(dev);
+               if (retval)
+                       goto out;
+       }
+
+       tmiofb_irq(-1, info);
+
+       tmiofb_hw_init(dev);
+
+       tmiofb_hw_mode(dev);
+
+       fb_set_suspend(info, 0);
+out:
+       release_console_sem();
+       return retval;
+}
+#else
+#define tmiofb_suspend NULL
+#define tmiofb_resume  NULL
+#endif
+
+static struct platform_driver tmiofb_driver = {
+       .driver.name    = "tmio-fb",
+       .driver.owner   = THIS_MODULE,
+       .probe          = tmiofb_probe,
+       .remove         = __devexit_p(tmiofb_remove),
+       .suspend        = tmiofb_suspend,
+       .resume         = tmiofb_resume,
+};
+
+/*--------------------------------------------------------------------------*/
+
+#ifndef MODULE
+static void __init tmiofb_setup(char *options)
+{
+       char *this_opt;
+
+       if (!options || !*options)
+               return;
+
+       while ((this_opt = strsep(&options, ",")) != NULL) {
+               if (!*this_opt)
+                       continue;
+               /*
+                * FIXME
+                */
+       }
+}
+#endif
+
+static int __init tmiofb_init(void)
+{
+#ifndef MODULE
+       char *option = NULL;
+
+       if (fb_get_options("tmiofb", &option))
+               return -ENODEV;
+       tmiofb_setup(option);
+#endif
+       return platform_driver_register(&tmiofb_driver);
+}
+
+static void __exit tmiofb_cleanup(void)
+{
+       platform_driver_unregister(&tmiofb_driver);
+}
+
+module_init(tmiofb_init);
+module_exit(tmiofb_cleanup);
+
+MODULE_DESCRIPTION("TMIO framebuffer driver");
+MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
+MODULE_LICENSE("GPL");
index 50744229c7a947b2d7fc5dfff928664755232165..6c2d37fdd3b91c12beed0bc5de1aaed89f066454 100644 (file)
@@ -516,10 +516,12 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
 
                err = uvesafb_exec(task);
                if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
-                       printk(KERN_ERR "uvesafb: Getting mode info block "
+                       printk(KERN_WARNING "uvesafb: Getting mode info block "
                                "for mode 0x%x failed (eax=0x%x, err=%d)\n",
                                *mode, (u32)task->t.regs.eax, err);
-                       return -EINVAL;
+                       mode++;
+                       par->vbe_modes_cnt--;
+                       continue;
                }
 
                mib = task->buf;
@@ -548,7 +550,10 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
                        mib->depth = mib->bits_per_pixel;
        }
 
-       return 0;
+       if (par->vbe_modes_cnt > 0)
+               return 0;
+       else
+               return -EINVAL;
 }
 
 /*
index e31bca8a0cb2d8a5ecc6394c449bbc91f1705dc1..5b2938903ac2bee26df3de078d6b4106c97ca413 100644 (file)
@@ -58,7 +58,6 @@ struct vga16fb_par {
                unsigned char   ClockingMode;     /* Seq-Controller:01h */
        } vga_state;
        struct vgastate state;
-       struct mutex open_lock;
        unsigned int ref_count;
        int palette_blanked, vesa_blanked, mode, isVGA;
        u8 misc, pel_msk, vss, clkdiv;
@@ -286,7 +285,6 @@ static int vga16fb_open(struct fb_info *info, int user)
 {
        struct vga16fb_par *par = info->par;
 
-       mutex_lock(&par->open_lock);
        if (!par->ref_count) {
                memset(&par->state, 0, sizeof(struct vgastate));
                par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
@@ -294,7 +292,6 @@ static int vga16fb_open(struct fb_info *info, int user)
                save_vga(&par->state);
        }
        par->ref_count++;
-       mutex_unlock(&par->open_lock);
 
        return 0;
 }
@@ -303,15 +300,12 @@ static int vga16fb_release(struct fb_info *info, int user)
 {
        struct vga16fb_par *par = info->par;
 
-       mutex_lock(&par->open_lock);
-       if (!par->ref_count) {
-               mutex_unlock(&par->open_lock);
+       if (!par->ref_count)
                return -EINVAL;
-       }
+
        if (par->ref_count == 1)
                restore_vga(&par->state);
        par->ref_count--;
-       mutex_unlock(&par->open_lock);
 
        return 0;
 }
@@ -1326,7 +1320,6 @@ static int __init vga16fb_probe(struct platform_device *dev)
        printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
        par = info->par;
 
-       mutex_init(&par->open_lock);
        par->isVGA = screen_info.orig_video_isVGA;
        par->palette_blanked = 0;
        par->vesa_blanked = 0;
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
new file mode 100644 (file)
index 0000000..e533b4b
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the VIA framebuffer driver (for Linux Kernel 2.6)
+#
+
+obj-$(CONFIG_FB_VIA) += viafb.o
+
+viafb-y        :=viafbdev.o hw.o iface.o  via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
new file mode 100644 (file)
index 0000000..632523f
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+void viafb_init_accel(void)
+{
+       viaparinfo->fbmem_free -= CURSOR_SIZE;
+       viaparinfo->cursor_start = viaparinfo->fbmem_free;
+       viaparinfo->fbmem_used += CURSOR_SIZE;
+
+       /* Reverse 8*1024 memory space for cursor image */
+       viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
+       viaparinfo->VQ_start = viaparinfo->fbmem_free;
+       viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
+       viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
+
+void viafb_init_2d_engine(void)
+{
+       u32 dwVQStartAddr, dwVQEndAddr;
+       u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
+
+       /* init 2D engine regs to reset 2D engine */
+       writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);
+
+       /* Init AGP and VQ regs */
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_K8M890:
+       case UNICHROME_P4M900:
+               writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
+               writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+               writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+               break;
+
+       default:
+               writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
+               writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+
+               writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
+               writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+               break;
+       }
+       if (viaparinfo->VQ_start != 0) {
+               /* Enable VQ */
+               dwVQStartAddr = viaparinfo->VQ_start;
+               dwVQEndAddr = viaparinfo->VQ_end;
+
+               dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
+               dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
+               dwVQStartEndH = 0x52000000 |
+                       ((dwVQStartAddr & 0xFF000000) >> 24) |
+                       ((dwVQEndAddr & 0xFF000000) >> 16);
+               dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M900:
+                       dwVQStartL |= 0x20000000;
+                       dwVQEndL |= 0x20000000;
+                       dwVQStartEndH |= 0x20000000;
+                       dwVQLen |= 0x20000000;
+                       break;
+               default:
+                       break;
+               }
+
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M900:
+                       writel(0x00100000,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSET);
+                       writel(dwVQStartEndH,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       writel(dwVQStartL,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       writel(dwVQEndL,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       writel(dwVQLen,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       writel(0x74301001,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       writel(0x00000000,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       break;
+               default:
+                       writel(0x00FE0000,
+                               viaparinfo->io_virt + VIA_REG_TRANSET);
+                       writel(0x080003FE,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x0A00027C,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x0B000260,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x0C000274,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x0D000264,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x0E000000,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x0F000020,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x1000027E,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x110002FE,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x200F0060,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+
+                       writel(0x00000006,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x40008C0F,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x44000000,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x45080C04,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x46800408,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+
+                       writel(dwVQStartEndH,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(dwVQStartL,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(dwVQEndL,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(dwVQLen,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       break;
+               }
+       } else {
+               /* Disable VQ */
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M900:
+                       writel(0x00100000,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSET);
+                       writel(0x74301000,
+                               viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+                       break;
+               default:
+                       writel(0x00FE0000,
+                               viaparinfo->io_virt + VIA_REG_TRANSET);
+                       writel(0x00000004,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x40008C0F,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x44000000,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x45080C04,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       writel(0x46800408,
+                               viaparinfo->io_virt + VIA_REG_TRANSPACE);
+                       break;
+               }
+       }
+
+       viafb_set_2d_color_depth(viaparinfo->bpp);
+
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
+
+       writel(VIA_PITCH_ENABLE |
+                  (((viaparinfo->hres *
+                     viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres *
+                                                  viaparinfo->
+                                                  bpp >> 3) >> 3) << 16)),
+                                       viaparinfo->io_virt + VIA_REG_PITCH);
+}
+
+void viafb_set_2d_color_depth(int bpp)
+{
+       u32 dwGEMode;
+
+       dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF;
+
+       switch (bpp) {
+       case 16:
+               dwGEMode |= VIA_GEM_16bpp;
+               break;
+       case 32:
+               dwGEMode |= VIA_GEM_32bpp;
+               break;
+       default:
+               dwGEMode |= VIA_GEM_8bpp;
+               break;
+       }
+
+       /* Set BPP and Pitch */
+       writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE);
+}
+
+void viafb_hw_cursor_init(void)
+{
+       /* Set Cursor Image Base Address */
+       writel(viaparinfo->cursor_start,
+               viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
+       writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
+}
+
+void viafb_show_hw_cursor(struct fb_info *info, int Status)
+{
+       u32 temp;
+       u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
+
+       temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+       switch (Status) {
+       case HW_Cursor_ON:
+               temp |= 0x1;
+               break;
+       case HW_Cursor_OFF:
+               temp &= 0xFFFFFFFE;
+               break;
+       }
+       switch (iga_path) {
+       case IGA2:
+               temp |= 0x80000000;
+               break;
+       case IGA1:
+       default:
+               temp &= 0x7FFFFFFF;
+       }
+       writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+}
+
+int viafb_wait_engine_idle(void)
+{
+       int loop = 0;
+
+       while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
+                       VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
+               cpu_relax();
+
+       while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
+                   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+                   (loop++ < MAXLOOP))
+               cpu_relax();
+
+       return loop >= MAXLOOP;
+}
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h
new file mode 100644 (file)
index 0000000..29bf854
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ACCEL_H__
+#define __ACCEL_H__
+
+#define FB_ACCEL_VIA_UNICHROME  50
+
+/* MMIO Base Address Definition */
+#define MMIO_VGABASE                0x8000
+#define MMIO_CR_READ                (MMIO_VGABASE + 0x3D4)
+#define MMIO_CR_WRITE               (MMIO_VGABASE + 0x3D5)
+#define MMIO_SR_READ                (MMIO_VGABASE + 0x3C4)
+#define MMIO_SR_WRITE               (MMIO_VGABASE + 0x3C5)
+
+/* HW Cursor Status Define */
+#define HW_Cursor_ON    0
+#define HW_Cursor_OFF   1
+
+#define CURSOR_SIZE     (8 * 1024)
+#define VQ_SIZE         (256 * 1024)
+
+#define VIA_MMIO_BLTBASE        0x200000
+#define VIA_MMIO_BLTSIZE        0x200000
+
+/* Defines for 2D registers */
+#define VIA_REG_GECMD           0x000
+#define VIA_REG_GEMODE          0x004
+#define VIA_REG_SRCPOS          0x008
+#define VIA_REG_DSTPOS          0x00C
+/* width and height */
+#define VIA_REG_DIMENSION       0x010
+#define VIA_REG_PATADDR         0x014
+#define VIA_REG_FGCOLOR         0x018
+#define VIA_REG_BGCOLOR         0x01C
+/* top and left of clipping */
+#define VIA_REG_CLIPTL          0x020
+/* bottom and right of clipping */
+#define VIA_REG_CLIPBR          0x024
+#define VIA_REG_OFFSET          0x028
+/* color key control */
+#define VIA_REG_KEYCONTROL      0x02C
+#define VIA_REG_SRCBASE         0x030
+#define VIA_REG_DSTBASE         0x034
+/* pitch of src and dst */
+#define VIA_REG_PITCH           0x038
+#define VIA_REG_MONOPAT0        0x03C
+#define VIA_REG_MONOPAT1        0x040
+/* from 0x100 to 0x1ff */
+#define VIA_REG_COLORPAT        0x100
+
+/* VIA_REG_PITCH(0x38): Pitch Setting */
+#define VIA_PITCH_ENABLE        0x80000000
+
+/* defines for VIA HW cursor registers */
+#define VIA_REG_CURSOR_MODE     0x2D0
+#define VIA_REG_CURSOR_POS      0x2D4
+#define VIA_REG_CURSOR_ORG      0x2D8
+#define VIA_REG_CURSOR_BG       0x2DC
+#define VIA_REG_CURSOR_FG       0x2E0
+
+/* VIA_REG_GEMODE(0x04): GE mode */
+#define VIA_GEM_8bpp            0x00000000
+#define VIA_GEM_16bpp           0x00000100
+#define VIA_GEM_32bpp           0x00000300
+
+/* VIA_REG_GECMD(0x00): 2D Engine Command  */
+#define VIA_GEC_NOOP            0x00000000
+#define VIA_GEC_BLT             0x00000001
+#define VIA_GEC_LINE            0x00000005
+
+/* Rotate Command */
+#define VIA_GEC_ROT             0x00000008
+
+#define VIA_GEC_SRC_XY          0x00000000
+#define VIA_GEC_SRC_LINEAR      0x00000010
+#define VIA_GEC_DST_XY          0x00000000
+#define VIA_GEC_DST_LINRAT      0x00000020
+
+#define VIA_GEC_SRC_FB          0x00000000
+#define VIA_GEC_SRC_SYS         0x00000040
+#define VIA_GEC_DST_FB          0x00000000
+#define VIA_GEC_DST_SYS         0x00000080
+
+/* source is mono */
+#define VIA_GEC_SRC_MONO        0x00000100
+/* pattern is mono */
+#define VIA_GEC_PAT_MONO        0x00000200
+/* mono src is opaque */
+#define VIA_GEC_MSRC_OPAQUE     0x00000000
+/* mono src is transparent */
+#define VIA_GEC_MSRC_TRANS      0x00000400
+/* pattern is in frame buffer */
+#define VIA_GEC_PAT_FB          0x00000000
+/* pattern is from reg setting */
+#define VIA_GEC_PAT_REG         0x00000800
+
+#define VIA_GEC_CLIP_DISABLE    0x00000000
+#define VIA_GEC_CLIP_ENABLE     0x00001000
+
+#define VIA_GEC_FIXCOLOR_PAT    0x00002000
+
+#define VIA_GEC_INCX            0x00000000
+#define VIA_GEC_DECY            0x00004000
+#define VIA_GEC_INCY            0x00000000
+#define VIA_GEC_DECX            0x00008000
+/* mono pattern is opaque */
+#define VIA_GEC_MPAT_OPAQUE     0x00000000
+/* mono pattern is transparent */
+#define VIA_GEC_MPAT_TRANS      0x00010000
+
+#define VIA_GEC_MONO_UNPACK     0x00000000
+#define VIA_GEC_MONO_PACK       0x00020000
+#define VIA_GEC_MONO_DWORD      0x00000000
+#define VIA_GEC_MONO_WORD       0x00040000
+#define VIA_GEC_MONO_BYTE       0x00080000
+
+#define VIA_GEC_LASTPIXEL_ON    0x00000000
+#define VIA_GEC_LASTPIXEL_OFF   0x00100000
+#define VIA_GEC_X_MAJOR         0x00000000
+#define VIA_GEC_Y_MAJOR         0x00200000
+#define VIA_GEC_QUICK_START     0x00800000
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS          0x400
+#define VIA_REG_CR_TRANSET      0x41C
+#define VIA_REG_CR_TRANSPACE   0x420
+#define VIA_REG_TRANSET         0x43C
+#define VIA_REG_TRANSPACE       0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+
+/* Command Regulator is busy */
+#define VIA_CMD_RGTR_BUSY       0x00000080
+/* 2D Engine is busy */
+#define VIA_2D_ENG_BUSY         0x00000002
+/* 3D Engine is busy */
+#define VIA_3D_ENG_BUSY         0x00000001
+/* Virtual Queue is busy */
+#define VIA_VR_QUEUE_BUSY       0x00020000
+
+#define MAXLOOP                 0xFFFFFF
+
+void viafb_init_accel(void);
+void viafb_init_2d_engine(void);
+void set_2d_color_depth(int);
+void viafb_hw_cursor_init(void);
+void viafb_show_hw_cursor(struct fb_info *info, int Status); int
+viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp);
+
+#endif /* __ACCEL_H__ */
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
new file mode 100644 (file)
index 0000000..dde95ed
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __CHIP_H__
+#define __CHIP_H__
+
+#include "global.h"
+
+/***************************************/
+/* Definition Graphic Chip Information */
+/***************************************/
+
+#define     PCI_VIA_VENDOR_ID       0x1106
+
+/* Define VIA Graphic Chip Name */
+#define     UNICHROME_CLE266        1
+#define     UNICHROME_CLE266_DID    0x3122
+#define     CLE266_REVISION_AX      0x0A
+#define     CLE266_REVISION_CX      0x0C
+
+#define     UNICHROME_K400          2
+#define     UNICHROME_K400_DID      0x7205
+
+#define     UNICHROME_K800          3
+#define     UNICHROME_K800_DID      0x3108
+
+#define     UNICHROME_PM800         4
+#define     UNICHROME_PM800_DID     0x3118
+
+#define     UNICHROME_CN700         5
+#define     UNICHROME_CN700_DID     0x3344
+
+#define     UNICHROME_CX700         6
+#define     UNICHROME_CX700_DID     0x3157
+#define     CX700_REVISION_700      0x0
+#define     CX700_REVISION_700M     0x1
+#define     CX700_REVISION_700M2    0x2
+
+#define     UNICHROME_CN750         7
+#define     UNICHROME_CN750_DID     0x3225
+
+#define     UNICHROME_K8M890        8
+#define     UNICHROME_K8M890_DID    0x3230
+
+#define     UNICHROME_P4M890        9
+#define     UNICHROME_P4M890_DID    0x3343
+
+#define     UNICHROME_P4M900        10
+#define     UNICHROME_P4M900_DID    0x3371
+
+#define     UNICHROME_VX800         11
+#define     UNICHROME_VX800_DID     0x1122
+
+/**************************************************/
+/* Definition TMDS Trasmitter Information         */
+/**************************************************/
+
+/* Definition TMDS Trasmitter Index */
+#define     NON_TMDS_TRANSMITTER    0x00
+#define     VT1632_TMDS             0x01
+#define     INTEGRATED_TMDS         0x42
+
+/* Definition TMDS Trasmitter I2C Slave Address */
+#define     VT1632_TMDS_I2C_ADDR    0x10
+
+/**************************************************/
+/* Definition LVDS Trasmitter Information         */
+/**************************************************/
+
+/* Definition LVDS Trasmitter Index */
+#define     NON_LVDS_TRANSMITTER    0x00
+#define     VT1631_LVDS             0x01
+#define     VT1636_LVDS             0x0E
+#define     INTEGRATED_LVDS         0x41
+
+/* Definition Digital Transmitter Mode */
+#define     TX_DATA_12_BITS         0x01
+#define     TX_DATA_24_BITS         0x02
+#define     TX_DATA_DDR_MODE        0x04
+#define     TX_DATA_SDR_MODE        0x08
+
+/* Definition LVDS Trasmitter I2C Slave Address */
+#define     VT1631_LVDS_I2C_ADDR    0x70
+#define     VT3271_LVDS_I2C_ADDR    0x80
+#define     VT1636_LVDS_I2C_ADDR    0x80
+
+struct tmds_chip_information {
+       int tmds_chip_name;
+       int tmds_chip_slave_addr;
+       int dvi_panel_id;
+       int data_mode;
+       int output_interface;
+       int i2c_port;
+       int device_type;
+};
+
+struct lvds_chip_information {
+       int lvds_chip_name;
+       int lvds_chip_slave_addr;
+       int data_mode;
+       int output_interface;
+       int i2c_port;
+};
+
+struct chip_information {
+       int gfx_chip_name;
+       int gfx_chip_revision;
+       int chip_on_slot;
+       struct tmds_chip_information tmds_chip_info;
+       struct lvds_chip_information lvds_chip_info;
+       struct lvds_chip_information lvds_chip_info2;
+};
+
+struct crt_setting_information {
+       int iga_path;
+       int h_active;
+       int v_active;
+       int bpp;
+       int refresh_rate;
+};
+
+struct tmds_setting_information {
+       int iga_path;
+       int h_active;
+       int v_active;
+       int bpp;
+       int refresh_rate;
+       int get_dvi_size_method;
+       int max_pixel_clock;
+       int dvi_panel_size;
+       int dvi_panel_hres;
+       int dvi_panel_vres;
+       int native_size;
+};
+
+struct lvds_setting_information {
+       int iga_path;
+       int h_active;
+       int v_active;
+       int bpp;
+       int refresh_rate;
+       int get_lcd_size_method;
+       int lcd_panel_id;
+       int lcd_panel_size;
+       int lcd_panel_hres;
+       int lcd_panel_vres;
+       int display_method;
+       int device_lcd_dualedge;
+       int LCDDithering;
+       int lcd_mode;
+       u32 vclk;               /*panel mode clock value */
+};
+
+struct GFX_DPA_SETTING {
+       int ClkRangeIndex;
+       u8 DVP0;                /* CR96[3:0] */
+       u8 DVP0DataDri_S1;      /* SR2A[5]   */
+       u8 DVP0DataDri_S;       /* SR1B[1]   */
+       u8 DVP0ClockDri_S1;     /* SR2A[4]   */
+       u8 DVP0ClockDri_S;      /* SR1E[2]   */
+       u8 DVP1;                /* CR9B[3:0] */
+       u8 DVP1Driving;         /* SR65[3:0], Data and Clock driving */
+       u8 DFPHigh;             /* CR97[3:0] */
+       u8 DFPLow;              /* CR99[3:0] */
+
+};
+
+struct VT1636_DPA_SETTING {
+       int PanelSizeID;
+       u8 CLK_SEL_ST1;
+       u8 CLK_SEL_ST2;
+};
+#endif /* __CHIP_H__ */
diff --git a/drivers/video/via/debug.h b/drivers/video/via/debug.h
new file mode 100644 (file)
index 0000000..86eacc2
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#ifndef VIAFB_DEBUG
+#define VIAFB_DEBUG 0
+#endif
+
+#if VIAFB_DEBUG
+#define DEBUG_MSG(f, a...)   printk(f, ## a)
+#else
+#define DEBUG_MSG(f, a...)
+#endif
+
+#define VIAFB_WARN 0
+#if VIAFB_WARN
+#define WARN_MSG(f, a...)   printk(f, ## a)
+#else
+#define WARN_MSG(f, a...)
+#endif
+
+#endif /* __DEBUG_H__ */
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
new file mode 100644 (file)
index 0000000..d696544
--- /dev/null
@@ -0,0 +1,682 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+static void tmds_register_write(int index, u8 data);
+static int tmds_register_read(int index);
+static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
+static int check_reduce_blanking_mode(int mode_index,
+       int refresh_rate);
+static int dvi_get_panel_size_from_DDCv1(void);
+static int dvi_get_panel_size_from_DDCv2(void);
+static unsigned char dvi_get_panel_info(void);
+static int viafb_dvi_query_EDID(void);
+
+static int check_tmds_chip(int device_id_subaddr, int device_id)
+{
+       if (tmds_register_read(device_id_subaddr) == device_id)
+               return OK;
+       else
+               return FAIL;
+}
+
+void viafb_init_dvi_size(void)
+{
+       DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
+       DEBUG_MSG(KERN_INFO
+               "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
+                 viaparinfo->tmds_setting_info->get_dvi_size_method);
+
+       switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
+       case GET_DVI_SIZE_BY_SYSTEM_BIOS:
+               break;
+       case GET_DVI_SZIE_BY_HW_STRAPPING:
+               break;
+       case GET_DVI_SIZE_BY_VGA_BIOS:
+       default:
+               dvi_get_panel_info();
+               break;
+       }
+       return;
+}
+
+int viafb_tmds_trasmitter_identify(void)
+{
+       unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
+
+       /* Turn on ouputting pad */
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_K8M890:
+           /*=* DFP Low Pad on *=*/
+               sr2a = viafb_read_reg(VIASR, SR2A);
+               viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+               break;
+
+       case UNICHROME_P4M900:
+       case UNICHROME_P4M890:
+               /* DFP Low Pad on */
+               sr2a = viafb_read_reg(VIASR, SR2A);
+               viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+               /* DVP0 Pad on */
+               sr1e = viafb_read_reg(VIASR, SR1E);
+               viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
+               break;
+
+       default:
+           /* DVP0/DVP1 Pad on */
+               sr1e = viafb_read_reg(VIASR, SR1E);
+               viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
+                       BIT5 + BIT6 + BIT7);
+           /* SR3E[1]Multi-function selection:
+           0 = Emulate I2C and DDC bus by GPIO2/3/4. */
+               sr3e = viafb_read_reg(VIASR, SR3E);
+               viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
+               break;
+       }
+
+       /* Check for VT1632: */
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
+       viaparinfo->chip_info->
+               tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+       viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
+       if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
+               /*
+                * Currently only support 12bits,dual edge,add 24bits mode later
+                */
+               tmds_register_write(0x08, 0x3b);
+
+               DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
+               DEBUG_MSG(KERN_INFO "\n %2d",
+                         viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
+               DEBUG_MSG(KERN_INFO "\n %2d",
+                         viaparinfo->chip_info->tmds_chip_info.i2c_port);
+               return OK;
+       } else {
+               viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
+               if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
+                   != FAIL) {
+                       tmds_register_write(0x08, 0x3b);
+                       DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
+                       DEBUG_MSG(KERN_INFO "\n %2d",
+                                 viaparinfo->chip_info->
+                                 tmds_chip_info.tmds_chip_name);
+                       DEBUG_MSG(KERN_INFO "\n %2d",
+                                 viaparinfo->chip_info->
+                                 tmds_chip_info.i2c_port);
+                       return OK;
+               }
+       }
+
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
+
+       if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
+           ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
+            (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
+               DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
+               return OK;
+       }
+
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_K8M890:
+               viafb_write_reg(SR2A, VIASR, sr2a);
+               break;
+
+       case UNICHROME_P4M900:
+       case UNICHROME_P4M890:
+               viafb_write_reg(SR2A, VIASR, sr2a);
+               viafb_write_reg(SR1E, VIASR, sr1e);
+               break;
+
+       default:
+               viafb_write_reg(SR1E, VIASR, sr1e);
+               viafb_write_reg(SR3E, VIASR, sr3e);
+               break;
+       }
+
+       viaparinfo->chip_info->
+               tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
+       viaparinfo->chip_info->tmds_chip_info.
+               tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+       return FAIL;
+}
+
+static void tmds_register_write(int index, u8 data)
+{
+       viaparinfo->i2c_stuff.i2c_port =
+               viaparinfo->chip_info->tmds_chip_info.i2c_port;
+
+       viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
+               tmds_chip_slave_addr, index,
+                    data);
+}
+
+static int tmds_register_read(int index)
+{
+       u8 data;
+
+       viaparinfo->i2c_stuff.i2c_port =
+               viaparinfo->chip_info->tmds_chip_info.i2c_port;
+       viafb_i2c_readbyte((u8) viaparinfo->chip_info->
+           tmds_chip_info.tmds_chip_slave_addr,
+                       (u8) index, &data);
+       return data;
+}
+
+static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
+{
+       viaparinfo->i2c_stuff.i2c_port =
+               viaparinfo->chip_info->tmds_chip_info.i2c_port;
+       viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
+                        tmds_chip_slave_addr, (u8) index, buff, buff_len);
+       return 0;
+}
+
+static int check_reduce_blanking_mode(int mode_index,
+       int refresh_rate)
+{
+       if (refresh_rate != 60)
+               return false;
+
+       switch (mode_index) {
+               /* Following modes have reduce blanking mode. */
+       case VIA_RES_1360X768:
+       case VIA_RES_1400X1050:
+       case VIA_RES_1440X900:
+       case VIA_RES_1600X900:
+       case VIA_RES_1680X1050:
+       case VIA_RES_1920X1080:
+       case VIA_RES_1920X1200:
+               break;
+
+       default:
+               DEBUG_MSG(KERN_INFO
+                         "This dvi mode %d have no reduce blanking mode!\n",
+                         mode_index);
+               return false;
+       }
+
+       return true;
+}
+
+/* DVI Set Mode */
+void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
+{
+       struct VideoModeTable *videoMode = NULL;
+       struct crt_mode_table *pDviTiming;
+       unsigned long desirePixelClock, maxPixelClock;
+       int status = 0;
+       videoMode = viafb_get_modetbl_pointer(video_index);
+       pDviTiming = videoMode->crtc;
+       desirePixelClock = pDviTiming->clk / 1000000;
+       maxPixelClock = (unsigned long)viaparinfo->
+               tmds_setting_info->max_pixel_clock;
+
+       DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
+
+       if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
+               /*Check if reduce-blanking mode is exist */
+               status =
+                   check_reduce_blanking_mode(video_index,
+                                              pDviTiming->refresh_rate);
+               if (status) {
+                       video_index += 100;     /*Use reduce-blanking mode */
+                       videoMode = viafb_get_modetbl_pointer(video_index);
+                       pDviTiming = videoMode->crtc;
+                       DEBUG_MSG(KERN_INFO
+                                 "DVI use reduce blanking mode %d!!\n",
+                                 video_index);
+               }
+       }
+       viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
+       viafb_set_output_path(DEVICE_DVI, set_iga,
+                       viaparinfo->chip_info->tmds_chip_info.output_interface);
+}
+
+/* Sense DVI Connector */
+int viafb_dvi_sense(void)
+{
+       u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
+               RegCR93 = 0, RegCR9B = 0, data;
+       int ret = false;
+
+       DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
+
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+               /* DI1 Pad on */
+               RegSR1E = viafb_read_reg(VIASR, SR1E);
+               viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
+
+               /* CR6B[0]VCK Input Selection: 1 = External clock. */
+               RegCR6B = viafb_read_reg(VIACR, CR6B);
+               viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
+
+               /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
+                  [0] Software Control Power Sequence */
+               RegCR91 = viafb_read_reg(VIACR, CR91);
+               viafb_write_reg(CR91, VIACR, 0x1D);
+
+               /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
+                  CR93[5] DI1 Clock Source: 1 = internal.
+                  CR93[4] DI1 Clock Polarity.
+                  CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
+               RegCR93 = viafb_read_reg(VIACR, CR93);
+               viafb_write_reg(CR93, VIACR, 0x01);
+       } else {
+               /* DVP0/DVP1 Pad on */
+               RegSR1E = viafb_read_reg(VIASR, SR1E);
+               viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
+
+               /* SR3E[1]Multi-function selection:
+                  0 = Emulate I2C and DDC bus by GPIO2/3/4. */
+               RegSR3E = viafb_read_reg(VIASR, SR3E);
+               viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
+
+               /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
+                  [0] Software Control Power Sequence */
+               RegCR91 = viafb_read_reg(VIACR, CR91);
+               viafb_write_reg(CR91, VIACR, 0x1D);
+
+               /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
+               display.CR9B[2:0] DVP1 Clock Adjust */
+               RegCR9B = viafb_read_reg(VIACR, CR9B);
+               viafb_write_reg(CR9B, VIACR, 0x01);
+       }
+
+       data = (u8) tmds_register_read(0x09);
+       if (data & 0x04)
+               ret = true;
+
+       if (ret == false) {
+               if (viafb_dvi_query_EDID())
+                       ret = true;
+       }
+
+       /* Restore status */
+       viafb_write_reg(SR1E, VIASR, RegSR1E);
+       viafb_write_reg(CR91, VIACR, RegCR91);
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+               viafb_write_reg(CR6B, VIACR, RegCR6B);
+               viafb_write_reg(CR93, VIACR, RegCR93);
+       } else {
+               viafb_write_reg(SR3E, VIASR, RegSR3E);
+               viafb_write_reg(CR9B, VIACR, RegCR9B);
+       }
+
+       return ret;
+}
+
+/* Query Flat Panel's EDID Table Version Through DVI Connector */
+static int viafb_dvi_query_EDID(void)
+{
+       u8 data0, data1;
+       int restore;
+
+       DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
+
+       restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+
+       data0 = (u8) tmds_register_read(0x00);
+       data1 = (u8) tmds_register_read(0x01);
+       if ((data0 == 0) && (data1 == 0xFF)) {
+               viaparinfo->chip_info->
+                       tmds_chip_info.tmds_chip_slave_addr = restore;
+               return EDID_VERSION_1;  /* Found EDID1 Table */
+       }
+
+       data0 = (u8) tmds_register_read(0x00);
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
+       if (data0 == 0x20)
+               return EDID_VERSION_2;  /* Found EDID2 Table */
+       else
+               return false;
+}
+
+/*
+ *
+ * int dvi_get_panel_size_from_DDCv1(void)
+ *
+ *     - Get Panel Size Using EDID1 Table
+ *
+ * Return Type:    int
+ *
+ */
+static int dvi_get_panel_size_from_DDCv1(void)
+{
+       int i, max_h = 0, max_v = 0, tmp, restore;
+       unsigned char rData;
+       unsigned char EDID_DATA[18];
+
+       DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
+
+       restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+
+       rData = tmds_register_read(0x23);
+       if (rData & 0x3C)
+               max_h = 640;
+       if (rData & 0xC0)
+               max_h = 720;
+       if (rData & 0x03)
+               max_h = 800;
+
+       rData = tmds_register_read(0x24);
+       if (rData & 0xC0)
+               max_h = 800;
+       if (rData & 0x1E)
+               max_h = 1024;
+       if (rData & 0x01)
+               max_h = 1280;
+
+       for (i = 0x25; i < 0x6D; i++) {
+               switch (i) {
+               case 0x26:
+               case 0x28:
+               case 0x2A:
+               case 0x2C:
+               case 0x2E:
+               case 0x30:
+               case 0x32:
+               case 0x34:
+                       rData = tmds_register_read(i);
+                       if (rData == 1)
+                               break;
+                       /* data = (data + 31) * 8 */
+                       tmp = (rData + 31) << 3;
+                       if (tmp > max_h)
+                               max_h = tmp;
+                       break;
+
+               case 0x36:
+               case 0x48:
+               case 0x5A:
+               case 0x6C:
+                       tmds_register_read_bytes(i, EDID_DATA, 10);
+                       if (!(EDID_DATA[0] || EDID_DATA[1])) {
+                               /* The first two byte must be zero. */
+                               if (EDID_DATA[3] == 0xFD) {
+                                       /* To get max pixel clock. */
+                                       viaparinfo->tmds_setting_info->
+                                       max_pixel_clock = EDID_DATA[9] * 10;
+                               }
+                       }
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       switch (max_h) {
+       case 640:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_640X480;
+               break;
+       case 800:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_800X600;
+               break;
+       case 1024:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1024X768;
+               break;
+       case 1280:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1280X1024;
+               break;
+       case 1400:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1400X1050;
+               break;
+       case 1440:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1440X1050;
+               break;
+       case 1600:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1600X1200;
+               break;
+       case 1920:
+               if (max_v == 1200) {
+                       viaparinfo->tmds_setting_info->dvi_panel_size =
+                               VIA_RES_1920X1200;
+               } else {
+                       viaparinfo->tmds_setting_info->dvi_panel_size =
+                               VIA_RES_1920X1080;
+               }
+
+               break;
+       default:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1024X768;
+               DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
+                                        set default panel size.\n", max_h);
+               break;
+       }
+
+       DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
+                 viaparinfo->tmds_setting_info->max_pixel_clock);
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
+       return viaparinfo->tmds_setting_info->dvi_panel_size;
+}
+
+/*
+ *
+ * int dvi_get_panel_size_from_DDCv2(void)
+ *
+ *     - Get Panel Size Using EDID2 Table
+ *
+ * Return Type:    int
+ *
+ */
+static int dvi_get_panel_size_from_DDCv2(void)
+{
+       int HSize = 0, restore;
+       unsigned char R_Buffer[2];
+
+       DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
+
+       restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
+
+       /* Horizontal: 0x76, 0x77 */
+       tmds_register_read_bytes(0x76, R_Buffer, 2);
+       HSize = R_Buffer[0];
+       HSize += R_Buffer[1] << 8;
+
+       switch (HSize) {
+       case 640:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_640X480;
+               break;
+       case 800:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_800X600;
+               break;
+       case 1024:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1024X768;
+               break;
+       case 1280:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1280X1024;
+               break;
+       case 1400:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1400X1050;
+               break;
+       case 1440:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1440X1050;
+               break;
+       case 1600:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1600X1200;
+               break;
+       default:
+               viaparinfo->tmds_setting_info->dvi_panel_size =
+                       VIA_RES_1024X768;
+               DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
+                                       set default panel size.\n", HSize);
+               break;
+       }
+
+       viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
+       return viaparinfo->tmds_setting_info->dvi_panel_size;
+}
+
+/*
+ *
+ * unsigned char dvi_get_panel_info(void)
+ *
+ *     - Get Panel Size
+ *
+ * Return Type:    unsigned char
+ */
+static unsigned char dvi_get_panel_info(void)
+{
+       unsigned char dvipanelsize;
+       DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
+
+       viafb_dvi_sense();
+       switch (viafb_dvi_query_EDID()) {
+       case 1:
+               dvi_get_panel_size_from_DDCv1();
+               break;
+       case 2:
+               dvi_get_panel_size_from_DDCv2();
+               break;
+       default:
+               break;
+       }
+
+       DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
+                 viaparinfo->tmds_setting_info->dvi_panel_size);
+       dvipanelsize = (unsigned char)(viaparinfo->
+               tmds_setting_info->dvi_panel_size);
+       return dvipanelsize;
+}
+
+/* If Disable DVI, turn off pad */
+void viafb_dvi_disable(void)
+{
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DVP0)
+               viafb_write_reg(SR1E, VIASR,
+               viafb_read_reg(VIASR, SR1E) & (~0xC0));
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DVP1)
+               viafb_write_reg(SR1E, VIASR,
+               viafb_read_reg(VIASR, SR1E) & (~0x30));
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
+               viafb_write_reg(SR2A, VIASR,
+               viafb_read_reg(VIASR, SR2A) & (~0x0C));
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
+               viafb_write_reg(SR2A, VIASR,
+               viafb_read_reg(VIASR, SR2A) & (~0x03));
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_TMDS)
+               /* Turn off TMDS power. */
+               viafb_write_reg(CRD2, VIACR,
+               viafb_read_reg(VIACR, CRD2) | 0x08);
+}
+
+/* If Enable DVI, turn off pad */
+void viafb_dvi_enable(void)
+{
+       u8 data;
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DVP0) {
+               viafb_write_reg(SR1E, VIASR,
+                       viafb_read_reg(VIASR, SR1E) | 0xC0);
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+                       tmds_register_write(0x88, 0x3b);
+               else
+                       /*clear CR91[5] to direct on display period
+                          in the secondary diplay path */
+                       viafb_write_reg(CR91, VIACR,
+                       viafb_read_reg(VIACR, CR91) & 0xDF);
+       }
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DVP1) {
+               viafb_write_reg(SR1E, VIASR,
+                       viafb_read_reg(VIASR, SR1E) | 0x30);
+
+               /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+                       tmds_register_write(0x88, 0x3b);
+               } else {
+                       /*clear CR91[5] to direct on display period
+                         in the secondary diplay path */
+                       viafb_write_reg(CR91, VIACR,
+                       viafb_read_reg(VIACR, CR91) & 0xDF);
+               }
+
+               /*fix DVI cannot enable on EPIA-M board */
+               if (viafb_platform_epia_dvi == 1) {
+                       viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
+                       viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
+                       if (viafb_bus_width == 24) {
+                               if (viafb_device_lcd_dualedge == 1)
+                                       data = 0x3F;
+                               else
+                                       data = 0x37;
+                               viafb_i2c_writebyte(viaparinfo->chip_info->
+                                            tmds_chip_info.
+                                            tmds_chip_slave_addr,
+                                            0x08, data);
+                       }
+               }
+       }
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
+               viafb_write_reg(SR2A, VIASR,
+                       viafb_read_reg(VIASR, SR2A) | 0x0C);
+               viafb_write_reg(CR91, VIACR,
+                       viafb_read_reg(VIACR, CR91) & 0xDF);
+       }
+
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
+               viafb_write_reg(SR2A, VIASR,
+                       viafb_read_reg(VIASR, SR2A) | 0x03);
+               viafb_write_reg(CR91, VIACR,
+                       viafb_read_reg(VIACR, CR91) & 0xDF);
+       }
+       if (viaparinfo->chip_info->
+               tmds_chip_info.output_interface == INTERFACE_TMDS) {
+               /* Turn on Display period in the panel path. */
+               viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
+
+               /* Turn on TMDS power. */
+               viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
+       }
+}
+
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
new file mode 100644 (file)
index 0000000..e1ec37f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __DVI_H__
+#define __DVI_H__
+
+/*Definition TMDS Device ID register*/
+#define     VT1632_DEVICE_ID_REG        0x02
+#define     VT1632_DEVICE_ID            0x92
+
+#define     GET_DVI_SIZE_BY_SYSTEM_BIOS     0x01
+#define     GET_DVI_SIZE_BY_VGA_BIOS        0x02
+#define     GET_DVI_SZIE_BY_HW_STRAPPING    0x03
+
+/* Definition DVI Panel ID*/
+/* Resolution: 640x480,   Channel: single, Dithering: Enable */
+#define     DVI_PANEL_ID0_640X480       0x00
+/* Resolution: 800x600,   Channel: single, Dithering: Enable */
+#define     DVI_PANEL_ID1_800x600       0x01
+/* Resolution: 1024x768,  Channel: single, Dithering: Enable */
+#define     DVI_PANEL_ID1_1024x768      0x02
+/* Resolution: 1280x768,  Channel: single, Dithering: Enable */
+#define     DVI_PANEL_ID1_1280x768      0x03
+/* Resolution: 1280x1024, Channel: dual,   Dithering: Enable */
+#define     DVI_PANEL_ID1_1280x1024     0x04
+/* Resolution: 1400x1050, Channel: dual,   Dithering: Enable */
+#define     DVI_PANEL_ID1_1400x1050     0x05
+/* Resolution: 1600x1200, Channel: dual,   Dithering: Enable */
+#define     DVI_PANEL_ID1_1600x1200     0x06
+
+/* Define the version of EDID*/
+#define     EDID_VERSION_1      1
+#define     EDID_VERSION_2      2
+
+#define     DEV_CONNECT_DVI     0x01
+#define     DEV_CONNECT_HDMI    0x02
+
+struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
+int viafb_dvi_sense(void);
+void viafb_dvi_disable(void);
+void viafb_dvi_enable(void);
+int viafb_tmds_trasmitter_identify(void);
+void viafb_init_dvi_size(void);
+void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
+
+#endif /* __DVI_H__ */
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
new file mode 100644 (file)
index 0000000..468be24
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+int viafb_platform_epia_dvi = STATE_OFF;
+int viafb_device_lcd_dualedge = STATE_OFF;
+int viafb_bus_width = 12;
+int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
+int viafb_memsize;
+int viafb_DeviceStatus = CRT_Device;
+int viafb_hotplug;
+int viafb_refresh = 60;
+int viafb_refresh1 = 60;
+int viafb_lcd_dsp_method = LCD_EXPANDSION;
+int viafb_lcd_mode = LCD_OPENLDI;
+int viafb_bpp = 32;
+int viafb_bpp1 = 32;
+int viafb_accel = 1;
+int viafb_CRT_ON = 1;
+int viafb_DVI_ON;
+int viafb_LCD_ON ;
+int viafb_LCD2_ON;
+int viafb_SAMM_ON;
+int viafb_dual_fb;
+int viafb_hotplug_Xres = 640;
+int viafb_hotplug_Yres = 480;
+int viafb_hotplug_bpp = 32;
+int viafb_hotplug_refresh = 60;
+unsigned int viafb_second_offset;
+int viafb_second_size;
+int viafb_primary_dev = None_Device;
+void __iomem *viafb_FB_MM;
+unsigned int viafb_second_xres = 640;
+unsigned int viafb_second_yres = 480;
+unsigned int viafb_second_virtual_xres;
+unsigned int viafb_second_virtual_yres;
+int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
+struct fb_cursor viacursor;
+struct fb_info *viafbinfo;
+struct fb_info *viafbinfo1;
+struct viafb_par *viaparinfo;
+struct viafb_par *viaparinfo1;
+
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
new file mode 100644 (file)
index 0000000..8e5263c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GLOBAL_H__
+#define __GLOBAL_H__
+
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/console.h>
+#include <linux/timer.h>
+
+#include "debug.h"
+
+#include "iface.h"
+#include "viafbdev.h"
+#include "chip.h"
+#include "debug.h"
+#include "accel.h"
+#include "share.h"
+#include "dvi.h"
+#include "viamode.h"
+#include "via_i2c.h"
+#include "hw.h"
+
+#include "lcd.h"
+#include "ioctl.h"
+#include "viamode.h"
+#include "via_utility.h"
+#include "vt1636.h"
+#include "tblDPASetting.h"
+#include "tbl1636.h"
+#include "viafbdev.h"
+
+/* External struct*/
+
+extern int viafb_platform_epia_dvi;
+extern int viafb_device_lcd_dualedge;
+extern int viafb_bus_width;
+extern int viafb_display_hardware_layout;
+extern struct offset offset_reg;
+extern struct viafb_par *viaparinfo;
+extern struct viafb_par *viaparinfo1;
+extern struct fb_info *viafbinfo;
+extern struct fb_info *viafbinfo1;
+extern int viafb_DeviceStatus;
+extern int viafb_refresh;
+extern int viafb_refresh1;
+extern int viafb_lcd_dsp_method;
+extern int viafb_lcd_mode;
+extern int viafb_bpp;
+extern int viafb_bpp1;
+
+extern int viafb_CRT_ON;
+extern int viafb_hotplug_Xres;
+extern int viafb_hotplug_Yres;
+extern int viafb_hotplug_bpp;
+extern int viafb_hotplug_refresh;
+extern int viafb_primary_dev;
+extern void __iomem *viafb_FB_MM;
+extern struct fb_cursor viacursor;
+
+extern unsigned int viafb_second_xres;
+extern unsigned int viafb_second_yres;
+extern int viafb_lcd_panel_id;
+
+#endif /* __GLOBAL_H__ */
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
new file mode 100644 (file)
index 0000000..fcd53ce
--- /dev/null
@@ -0,0 +1,2865 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+static const struct pci_device_id_info pciidlist[] = {
+       {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266},
+       {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800},
+       {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400},
+       {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800},
+       {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700},
+       {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890},
+       {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890},
+       {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700},
+       {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900},
+       {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750},
+       {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800},
+       {0, 0, 0}
+};
+
+struct offset offset_reg = {
+       /* IGA1 Offset Register */
+       {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } },
+       /* IGA2 Offset Register */
+       {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } }
+};
+
+static struct pll_map pll_value[] = {
+       {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M},
+       {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M},
+       {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M},
+       {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M},
+       {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M},
+       {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M},
+       {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M},
+       {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M},
+       {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M},
+       {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M},
+       {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M},
+       {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M},
+       {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M},
+       {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M},
+       {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M},
+       {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M},
+       {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M},
+       {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M},
+       {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M},
+       {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M},
+       {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M},
+       {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M},
+       {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M},
+       {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M},
+       {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M},
+       {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M},
+       {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M},
+       {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M},
+       {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M},
+       {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M},
+       {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M},
+       {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M},
+       {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M},
+       {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M},
+       {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M},
+       {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M},
+       {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M},
+       {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M},
+       {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M,
+        CX700_101_000M},
+       {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M,
+        CX700_106_500M},
+       {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M,
+        CX700_108_000M},
+       {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M,
+        CX700_113_309M},
+       {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M,
+        CX700_118_840M},
+       {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M,
+        CX700_119_000M},
+       {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M,
+        CX700_121_750M},
+       {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M,
+        CX700_125_104M},
+       {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M,
+        CX700_133_308M},
+       {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M,
+        CX700_135_000M},
+       {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M,
+        CX700_136_700M},
+       {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M,
+        CX700_138_400M},
+       {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M,
+        CX700_146_760M},
+       {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M,
+        CX700_153_920M},
+       {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M,
+        CX700_156_000M},
+       {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M,
+        CX700_157_500M},
+       {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M,
+        CX700_162_000M},
+       {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M,
+        CX700_187_000M},
+       {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M,
+        CX700_193_295M},
+       {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M,
+        CX700_202_500M},
+       {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M,
+        CX700_204_000M},
+       {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M,
+        CX700_218_500M},
+       {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M,
+        CX700_234_000M},
+       {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M,
+        CX700_267_250M},
+       {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M,
+        CX700_297_500M},
+       {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M},
+       {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M,
+        CX700_172_798M},
+       {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M,
+        CX700_122_614M},
+       {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M},
+       {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M,
+        CX700_148_500M}
+};
+
+static struct fifo_depth_select display_fifo_depth_reg = {
+       /* IGA1 FIFO Depth_Select */
+       {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
+       /* IGA2 FIFO Depth_Select */
+       {IGA2_FIFO_DEPTH_SELECT_REG_NUM,
+        {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
+};
+
+static struct fifo_threshold_select fifo_threshold_select_reg = {
+       /* IGA1 FIFO Threshold Select */
+       {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
+       /* IGA2 FIFO Threshold Select */
+       {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
+};
+
+static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
+       /* IGA1 FIFO High Threshold Select */
+       {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
+       /* IGA2 FIFO High Threshold Select */
+       {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
+};
+
+static struct display_queue_expire_num display_queue_expire_num_reg = {
+       /* IGA1 Display Queue Expire Num */
+       {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
+       /* IGA2 Display Queue Expire Num */
+       {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
+};
+
+/* Definition Fetch Count Registers*/
+static struct fetch_count fetch_count_reg = {
+       /* IGA1 Fetch Count Register */
+       {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
+       /* IGA2 Fetch Count Register */
+       {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
+};
+
+static struct iga1_crtc_timing iga1_crtc_reg = {
+       /* IGA1 Horizontal Total */
+       {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
+       /* IGA1 Horizontal Addressable Video */
+       {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
+       /* IGA1 Horizontal Blank Start */
+       {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
+       /* IGA1 Horizontal Blank End */
+       {IGA1_HOR_BLANK_END_REG_NUM,
+        {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
+       /* IGA1 Horizontal Sync Start */
+       {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
+       /* IGA1 Horizontal Sync End */
+       {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
+       /* IGA1 Vertical Total */
+       {IGA1_VER_TOTAL_REG_NUM,
+        {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
+       /* IGA1 Vertical Addressable Video */
+       {IGA1_VER_ADDR_REG_NUM,
+        {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
+       /* IGA1 Vertical Blank Start */
+       {IGA1_VER_BLANK_START_REG_NUM,
+        {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
+       /* IGA1 Vertical Blank End */
+       {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
+       /* IGA1 Vertical Sync Start */
+       {IGA1_VER_SYNC_START_REG_NUM,
+        {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
+       /* IGA1 Vertical Sync End */
+       {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
+};
+
+static struct iga2_crtc_timing iga2_crtc_reg = {
+       /* IGA2 Horizontal Total */
+       {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
+       /* IGA2 Horizontal Addressable Video */
+       {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
+       /* IGA2 Horizontal Blank Start */
+       {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
+       /* IGA2 Horizontal Blank End */
+       {IGA2_HOR_BLANK_END_REG_NUM,
+        {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
+       /* IGA2 Horizontal Sync Start */
+       {IGA2_HOR_SYNC_START_REG_NUM,
+        {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
+       /* IGA2 Horizontal Sync End */
+       {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
+       /* IGA2 Vertical Total */
+       {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
+       /* IGA2 Vertical Addressable Video */
+       {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
+       /* IGA2 Vertical Blank Start */
+       {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
+       /* IGA2 Vertical Blank End */
+       {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
+       /* IGA2 Vertical Sync Start */
+       {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
+       /* IGA2 Vertical Sync End */
+       {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
+};
+
+static struct rgbLUT palLUT_table[] = {
+       /* {R,G,B} */
+       /* Index 0x00~0x03 */
+       {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
+                                                                    0x2A,
+                                                                    0x2A},
+       /* Index 0x04~0x07 */
+       {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
+                                                                    0x2A,
+                                                                    0x2A},
+       /* Index 0x08~0x0B */
+       {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
+                                                                    0x3F,
+                                                                    0x3F},
+       /* Index 0x0C~0x0F */
+       {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
+                                                                    0x3F,
+                                                                    0x3F},
+       /* Index 0x10~0x13 */
+       {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
+                                                                    0x0B,
+                                                                    0x0B},
+       /* Index 0x14~0x17 */
+       {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
+                                                                    0x18,
+                                                                    0x18},
+       /* Index 0x18~0x1B */
+       {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
+                                                                    0x28,
+                                                                    0x28},
+       /* Index 0x1C~0x1F */
+       {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
+                                                                    0x3F,
+                                                                    0x3F},
+       /* Index 0x20~0x23 */
+       {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
+                                                                    0x00,
+                                                                    0x3F},
+       /* Index 0x24~0x27 */
+       {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
+                                                                    0x00,
+                                                                    0x10},
+       /* Index 0x28~0x2B */
+       {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
+                                                                    0x2F,
+                                                                    0x00},
+       /* Index 0x2C~0x2F */
+       {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
+                                                                    0x3F,
+                                                                    0x00},
+       /* Index 0x30~0x33 */
+       {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
+                                                                    0x3F,
+                                                                    0x2F},
+       /* Index 0x34~0x37 */
+       {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
+                                                                    0x10,
+                                                                    0x3F},
+       /* Index 0x38~0x3B */
+       {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
+                                                                    0x1F,
+                                                                    0x3F},
+       /* Index 0x3C~0x3F */
+       {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
+                                                                    0x1F,
+                                                                    0x27},
+       /* Index 0x40~0x43 */
+       {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
+                                                                    0x3F,
+                                                                    0x1F},
+       /* Index 0x44~0x47 */
+       {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
+                                                                    0x3F,
+                                                                    0x1F},
+       /* Index 0x48~0x4B */
+       {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
+                                                                    0x3F,
+                                                                    0x37},
+       /* Index 0x4C~0x4F */
+       {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
+                                                                    0x27,
+                                                                    0x3F},
+       /* Index 0x50~0x53 */
+       {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
+                                                                    0x2D,
+                                                                    0x3F},
+       /* Index 0x54~0x57 */
+       {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
+                                                                    0x2D,
+                                                                    0x31},
+       /* Index 0x58~0x5B */
+       {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
+                                                                    0x3A,
+                                                                    0x2D},
+       /* Index 0x5C~0x5F */
+       {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
+                                                                    0x3F,
+                                                                    0x2D},
+       /* Index 0x60~0x63 */
+       {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
+                                                                    0x3F,
+                                                                    0x3A},
+       /* Index 0x64~0x67 */
+       {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
+                                                                    0x31,
+                                                                    0x3F},
+       /* Index 0x68~0x6B */
+       {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
+                                                                    0x00,
+                                                                    0x1C},
+       /* Index 0x6C~0x6F */
+       {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
+                                                                    0x00,
+                                                                    0x07},
+       /* Index 0x70~0x73 */
+       {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
+                                                                    0x15,
+                                                                    0x00},
+       /* Index 0x74~0x77 */
+       {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
+                                                                    0x1C,
+                                                                    0x00},
+       /* Index 0x78~0x7B */
+       {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
+                                                                    0x1C,
+                                                                    0x15},
+       /* Index 0x7C~0x7F */
+       {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
+                                                                    0x07,
+                                                                    0x1C},
+       /* Index 0x80~0x83 */
+       {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
+                                                                    0x0E,
+                                                                    0x1C},
+       /* Index 0x84~0x87 */
+       {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
+                                                                    0x0E,
+                                                                    0x11},
+       /* Index 0x88~0x8B */
+       {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
+                                                                    0x18,
+                                                                    0x0E},
+       /* Index 0x8C~0x8F */
+       {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
+                                                                    0x1C,
+                                                                    0x0E},
+       /* Index 0x90~0x93 */
+       {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
+                                                                    0x1C,
+                                                                    0x18},
+       /* Index 0x94~0x97 */
+       {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
+                                                                    0x11,
+                                                                    0x1C},
+       /* Index 0x98~0x9B */
+       {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
+                                                                    0x14,
+                                                                    0x1C},
+       /* Index 0x9C~0x9F */
+       {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
+                                                                    0x14,
+                                                                    0x16},
+       /* Index 0xA0~0xA3 */
+       {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
+                                                                    0x1A,
+                                                                    0x14},
+       /* Index 0xA4~0xA7 */
+       {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
+                                                                    0x1C,
+                                                                    0x14},
+       /* Index 0xA8~0xAB */
+       {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
+                                                                    0x1C,
+                                                                    0x1A},
+       /* Index 0xAC~0xAF */
+       {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
+                                                                    0x16,
+                                                                    0x1C},
+       /* Index 0xB0~0xB3 */
+       {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
+                                                                    0x00,
+                                                                    0x10},
+       /* Index 0xB4~0xB7 */
+       {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
+                                                                    0x00,
+                                                                    0x04},
+       /* Index 0xB8~0xBB */
+       {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
+                                                                    0x0C,
+                                                                    0x00},
+       /* Index 0xBC~0xBF */
+       {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
+                                                                    0x10,
+                                                                    0x00},
+       /* Index 0xC0~0xC3 */
+       {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
+                                                                    0x10,
+                                                                    0x0C},
+       /* Index 0xC4~0xC7 */
+       {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
+                                                                    0x04,
+                                                                    0x10},
+       /* Index 0xC8~0xCB */
+       {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
+                                                                    0x08,
+                                                                    0x10},
+       /* Index 0xCC~0xCF */
+       {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
+                                                                    0x08,
+                                                                    0x0A},
+       /* Index 0xD0~0xD3 */
+       {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
+                                                                    0x0E,
+                                                                    0x08},
+       /* Index 0xD4~0xD7 */
+       {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
+                                                                    0x10,
+                                                                    0x08},
+       /* Index 0xD8~0xDB */
+       {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
+                                                                    0x10,
+                                                                    0x0E},
+       /* Index 0xDC~0xDF */
+       {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
+                                                                    0x0A,
+                                                                    0x10},
+       /* Index 0xE0~0xE3 */
+       {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
+                                                                    0x0B,
+                                                                    0x10},
+       /* Index 0xE4~0xE7 */
+       {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
+                                                                    0x0B,
+                                                                    0x0C},
+       /* Index 0xE8~0xEB */
+       {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
+                                                                    0x0F,
+                                                                    0x0B},
+       /* Index 0xEC~0xEF */
+       {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
+                                                                    0x10,
+                                                                    0x0B},
+       /* Index 0xF0~0xF3 */
+       {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
+                                                                    0x10,
+                                                                    0x0F},
+       /* Index 0xF4~0xF7 */
+       {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
+                                                                    0x0C,
+                                                                    0x10},
+       /* Index 0xF8~0xFB */
+       {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
+                                                                    0x00,
+                                                                    0x00},
+       /* Index 0xFC~0xFF */
+       {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
+                                                                    0x00,
+                                                                    0x00}
+};
+
+static void set_crt_output_path(int set_iga);
+static void dvi_patch_skew_dvp0(void);
+static void dvi_patch_skew_dvp1(void);
+static void dvi_patch_skew_dvp_low(void);
+static void set_dvi_output_path(int set_iga, int output_interface);
+static void set_lcd_output_path(int set_iga, int output_interface);
+static int search_mode_setting(int ModeInfoIndex);
+static void load_fix_bit_crtc_reg(void);
+static void init_gfx_chip_info(void);
+static void init_tmds_chip_info(void);
+static void init_lvds_chip_info(void);
+static void device_screen_off(void);
+static void device_screen_on(void);
+static void set_display_channel(void);
+static void device_off(void);
+static void device_on(void);
+static void enable_second_display_channel(void);
+static void disable_second_display_channel(void);
+static int get_fb_size_from_pci(void);
+
+void viafb_write_reg(u8 index, u16 io_port, u8 data)
+{
+       outb(index, io_port);
+       outb(data, io_port + 1);
+       /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
+}
+u8 viafb_read_reg(int io_port, u8 index)
+{
+       outb(index, io_port);
+       return inb(io_port + 1);
+}
+
+void viafb_lock_crt(void)
+{
+       viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
+}
+
+void viafb_unlock_crt(void)
+{
+       viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
+       viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
+}
+
+void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask)
+{
+       u8 tmp;
+
+       outb(index, io_port);
+       tmp = inb(io_port + 1);
+       outb((data & mask) | (tmp & (~mask)), io_port + 1);
+       /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
+}
+
+void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
+{
+       outb(index, LUT_INDEX_WRITE);
+       outb(r, LUT_DATA);
+       outb(g, LUT_DATA);
+       outb(b, LUT_DATA);
+}
+
+/*Set IGA path for each device*/
+void viafb_set_iga_path(void)
+{
+
+       if (viafb_SAMM_ON == 1) {
+               if (viafb_CRT_ON) {
+                       if (viafb_primary_dev == CRT_Device)
+                               viaparinfo->crt_setting_info->iga_path = IGA1;
+                       else
+                               viaparinfo->crt_setting_info->iga_path = IGA2;
+               }
+
+               if (viafb_DVI_ON) {
+                       if (viafb_primary_dev == DVI_Device)
+                               viaparinfo->tmds_setting_info->iga_path = IGA1;
+                       else
+                               viaparinfo->tmds_setting_info->iga_path = IGA2;
+               }
+
+               if (viafb_LCD_ON) {
+                       if (viafb_primary_dev == LCD_Device) {
+                               if (viafb_dual_fb &&
+                                       (viaparinfo->chip_info->gfx_chip_name ==
+                                       UNICHROME_CLE266)) {
+                                       viaparinfo->
+                                       lvds_setting_info->iga_path = IGA2;
+                                       viaparinfo->
+                                       crt_setting_info->iga_path = IGA1;
+                                       viaparinfo->
+                                       tmds_setting_info->iga_path = IGA1;
+                               } else
+                                       viaparinfo->
+                                       lvds_setting_info->iga_path = IGA1;
+                       } else {
+                               viaparinfo->lvds_setting_info->iga_path = IGA2;
+                       }
+               }
+               if (viafb_LCD2_ON) {
+                       if (LCD2_Device == viafb_primary_dev)
+                               viaparinfo->lvds_setting_info2->iga_path = IGA1;
+                       else
+                               viaparinfo->lvds_setting_info2->iga_path = IGA2;
+               }
+       } else {
+               viafb_SAMM_ON = 0;
+
+               if (viafb_CRT_ON && viafb_LCD_ON) {
+                       viaparinfo->crt_setting_info->iga_path = IGA1;
+                       viaparinfo->lvds_setting_info->iga_path = IGA2;
+               } else if (viafb_CRT_ON && viafb_DVI_ON) {
+                       viaparinfo->crt_setting_info->iga_path = IGA1;
+                       viaparinfo->tmds_setting_info->iga_path = IGA2;
+               } else if (viafb_LCD_ON && viafb_DVI_ON) {
+                       viaparinfo->tmds_setting_info->iga_path = IGA1;
+                       viaparinfo->lvds_setting_info->iga_path = IGA2;
+               } else if (viafb_LCD_ON && viafb_LCD2_ON) {
+                       viaparinfo->lvds_setting_info->iga_path = IGA2;
+                       viaparinfo->lvds_setting_info2->iga_path = IGA2;
+               } else if (viafb_CRT_ON) {
+                       viaparinfo->crt_setting_info->iga_path = IGA1;
+               } else if (viafb_LCD_ON) {
+                       viaparinfo->lvds_setting_info->iga_path = IGA2;
+               } else if (viafb_DVI_ON) {
+                       viaparinfo->tmds_setting_info->iga_path = IGA1;
+               }
+       }
+}
+
+void viafb_set_start_addr(void)
+{
+       unsigned long offset = 0, tmp = 0, size = 0;
+       unsigned long length;
+
+       DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n");
+       viafb_unlock_crt();
+       /* update starting address of IGA1 */
+       viafb_write_reg(CR0C, VIACR, 0x00);     /*initial starting address */
+       viafb_write_reg(CR0D, VIACR, 0x00);
+       viafb_write_reg(CR34, VIACR, 0x00);
+       viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F);
+
+       if (viafb_dual_fb) {
+               viaparinfo->iga_path = IGA1;
+               viaparinfo1->iga_path = IGA2;
+       }
+
+       if (viafb_SAMM_ON == 1) {
+               if (!viafb_dual_fb) {
+                       if (viafb_second_size)
+                               size = viafb_second_size * 1024 * 1024;
+                       else
+                               size = 8 * 1024 * 1024;
+               } else {
+
+                       size = viaparinfo1->memsize;
+               }
+               offset = viafb_second_offset;
+               DEBUG_MSG(KERN_INFO
+                         "viafb_second_size=%lx, second start_adddress=%lx\n",
+                         size, offset);
+       }
+       if (viafb_SAMM_ON == 1) {
+               offset = offset >> 3;
+
+               tmp = viafb_read_reg(VIACR, 0x62) & 0x01;
+               tmp |= (offset & 0x7F) << 1;
+               viafb_write_reg(CR62, VIACR, tmp);
+               viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7));
+               viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15));
+               viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23));
+       } else {
+               /* update starting address */
+               viafb_write_reg(CR62, VIACR, 0x00);
+               viafb_write_reg(CR63, VIACR, 0x00);
+               viafb_write_reg(CR64, VIACR, 0x00);
+               viafb_write_reg(CRA3, VIACR, 0x00);
+       }
+
+       if (viafb_SAMM_ON == 1) {
+               if (viafb_accel) {
+                       if (!viafb_dual_fb)
+                               length = size - viaparinfo->fbmem_used;
+                       else
+                               length = size - viaparinfo1->fbmem_used;
+               } else
+                       length = size;
+               offset = (unsigned long)(void *)viafb_FB_MM +
+                       viafb_second_offset;
+               memset((void *)offset, 0, length);
+       }
+
+       viafb_lock_crt();
+}
+
+void viafb_set_output_path(int device, int set_iga, int output_interface)
+{
+       switch (device) {
+       case DEVICE_CRT:
+               set_crt_output_path(set_iga);
+               break;
+       case DEVICE_DVI:
+               set_dvi_output_path(set_iga, output_interface);
+               break;
+       case DEVICE_LCD:
+               set_lcd_output_path(set_iga, output_interface);
+               break;
+       }
+}
+
+static void set_crt_output_path(int set_iga)
+{
+       viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
+
+       switch (set_iga) {
+       case IGA1:
+               viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
+               break;
+       case IGA2:
+       case IGA1_IGA2:
+               viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
+               viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
+               if (set_iga == IGA1_IGA2)
+                       viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
+               break;
+       }
+}
+
+static void dvi_patch_skew_dvp0(void)
+{
+       /* Reset data driving first: */
+       viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
+       viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
+
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_P4M890:
+               {
+                       if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
+                               (viaparinfo->tmds_setting_info->v_active ==
+                               1200))
+                               viafb_write_reg_mask(CR96, VIACR, 0x03,
+                                              BIT0 + BIT1 + BIT2);
+                       else
+                               viafb_write_reg_mask(CR96, VIACR, 0x07,
+                                              BIT0 + BIT1 + BIT2);
+                       break;
+               }
+
+       case UNICHROME_P4M900:
+               {
+                       viafb_write_reg_mask(CR96, VIACR, 0x07,
+                                      BIT0 + BIT1 + BIT2 + BIT3);
+                       viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
+                       viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
+                       break;
+               }
+
+       default:
+               {
+                       break;
+               }
+       }
+}
+
+static void dvi_patch_skew_dvp1(void)
+{
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_CX700:
+               {
+                       break;
+               }
+
+       default:
+               {
+                       break;
+               }
+       }
+}
+
+static void dvi_patch_skew_dvp_low(void)
+{
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_K8M890:
+               {
+                       viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
+                       break;
+               }
+
+       case UNICHROME_P4M900:
+               {
+                       viafb_write_reg_mask(CR99, VIACR, 0x08,
+                                      BIT0 + BIT1 + BIT2 + BIT3);
+                       break;
+               }
+
+       case UNICHROME_P4M890:
+               {
+                       viafb_write_reg_mask(CR99, VIACR, 0x0F,
+                                      BIT0 + BIT1 + BIT2 + BIT3);
+                       break;
+               }
+
+       default:
+               {
+                       break;
+               }
+       }
+}
+
+static void set_dvi_output_path(int set_iga, int output_interface)
+{
+       switch (output_interface) {
+       case INTERFACE_DVP0:
+               viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
+
+               if (set_iga == IGA1) {
+                       viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
+                       viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 +
+                               BIT5 + BIT7);
+               } else {
+                       viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+                       viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 +
+                               BIT5 + BIT7);
+               }
+
+               viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
+
+               dvi_patch_skew_dvp0();
+               break;
+
+       case INTERFACE_DVP1:
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+                       if (set_iga == IGA1)
+                               viafb_write_reg_mask(CR93, VIACR, 0x21,
+                                              BIT0 + BIT5 + BIT7);
+                       else
+                               viafb_write_reg_mask(CR93, VIACR, 0xA1,
+                                              BIT0 + BIT5 + BIT7);
+               } else {
+                       if (set_iga == IGA1)
+                               viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
+                       else
+                               viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+               }
+
+               viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
+               dvi_patch_skew_dvp1();
+               break;
+       case INTERFACE_DFP_HIGH:
+               if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) {
+                       if (set_iga == IGA1) {
+                               viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
+                               viafb_write_reg_mask(CR97, VIACR, 0x03,
+                                              BIT0 + BIT1 + BIT4);
+                       } else {
+                               viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+                               viafb_write_reg_mask(CR97, VIACR, 0x13,
+                                              BIT0 + BIT1 + BIT4);
+                       }
+               }
+               viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
+               break;
+
+       case INTERFACE_DFP_LOW:
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+                       break;
+
+               if (set_iga == IGA1) {
+                       viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+                       viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
+               } else {
+                       viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+                       viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+               }
+
+               viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+               dvi_patch_skew_dvp_low();
+               break;
+
+       case INTERFACE_TMDS:
+               if (set_iga == IGA1)
+                       viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+               else
+                       viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+               break;
+       }
+
+       if (set_iga == IGA2) {
+               enable_second_display_channel();
+               /* Disable LCD Scaling */
+               viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
+       }
+}
+
+static void set_lcd_output_path(int set_iga, int output_interface)
+{
+       DEBUG_MSG(KERN_INFO
+                 "set_lcd_output_path, iga:%d,out_interface:%d\n",
+                 set_iga, output_interface);
+       switch (set_iga) {
+       case IGA1:
+               viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
+               viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+
+               disable_second_display_channel();
+               break;
+
+       case IGA2:
+               viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
+               viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+
+               enable_second_display_channel();
+               break;
+
+       case IGA1_IGA2:
+               viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
+               viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+
+               disable_second_display_channel();
+               break;
+       }
+
+       switch (output_interface) {
+       case INTERFACE_DVP0:
+               if (set_iga == IGA1) {
+                       viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
+               } else {
+                       viafb_write_reg(CR91, VIACR, 0x00);
+                       viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+               }
+               break;
+
+       case INTERFACE_DVP1:
+               if (set_iga == IGA1)
+                       viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
+               else {
+                       viafb_write_reg(CR91, VIACR, 0x00);
+                       viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+               }
+               break;
+
+       case INTERFACE_DFP_HIGH:
+               if (set_iga == IGA1)
+                       viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
+               else {
+                       viafb_write_reg(CR91, VIACR, 0x00);
+                       viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
+                       viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+               }
+               break;
+
+       case INTERFACE_DFP_LOW:
+               if (set_iga == IGA1)
+                       viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+               else {
+                       viafb_write_reg(CR91, VIACR, 0x00);
+                       viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+                       viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+               }
+
+               break;
+
+       case INTERFACE_DFP:
+               if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
+                   || (UNICHROME_P4M890 ==
+                   viaparinfo->chip_info->gfx_chip_name))
+                       viafb_write_reg_mask(CR97, VIACR, 0x84,
+                                      BIT7 + BIT2 + BIT1 + BIT0);
+               if (set_iga == IGA1) {
+                       viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
+                       viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+               } else {
+                       viafb_write_reg(CR91, VIACR, 0x00);
+                       viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
+                       viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+               }
+               break;
+
+       case INTERFACE_LVDS0:
+       case INTERFACE_LVDS0LVDS1:
+               if (set_iga == IGA1)
+                       viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+               else
+                       viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+
+               break;
+
+       case INTERFACE_LVDS1:
+               if (set_iga == IGA1)
+                       viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
+               else
+                       viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
+               break;
+       }
+}
+
+/* Search Mode Index */
+static int search_mode_setting(int ModeInfoIndex)
+{
+       int i = 0;
+
+       while ((i < NUM_TOTAL_MODETABLE) &&
+                       (ModeInfoIndex != CLE266Modes[i].ModeIndex))
+               i++;
+       if (i >= NUM_TOTAL_MODETABLE)
+               i = 0;
+       return i;
+
+}
+
+struct VideoModeTable *viafb_get_modetbl_pointer(int Index)
+{
+       struct VideoModeTable *TmpTbl = NULL;
+       TmpTbl = &CLE266Modes[search_mode_setting(Index)];
+       return TmpTbl;
+}
+
+struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index)
+{
+       struct VideoModeTable *TmpTbl = NULL;
+       int i = 0;
+       while ((i < NUM_TOTAL_CEA_MODES) &&
+                       (Index != CEA_HDMI_Modes[i].ModeIndex))
+               i++;
+       if ((i < NUM_TOTAL_CEA_MODES))
+               TmpTbl = &CEA_HDMI_Modes[i];
+        else {
+               /*Still use general timing if don't find CEA timing */
+               i = 0;
+               while ((i < NUM_TOTAL_MODETABLE) &&
+                               (Index != CLE266Modes[i].ModeIndex))
+                      i++;
+               if (i >= NUM_TOTAL_MODETABLE)
+                       i = 0;
+               TmpTbl = &CLE266Modes[i];
+       }
+       return TmpTbl;
+}
+
+static void load_fix_bit_crtc_reg(void)
+{
+       /* always set to 1 */
+       viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
+       /* line compare should set all bits = 1 (extend modes) */
+       viafb_write_reg(CR18, VIACR, 0xff);
+       /* line compare should set all bits = 1 (extend modes) */
+       viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
+       /* line compare should set all bits = 1 (extend modes) */
+       viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
+       /* line compare should set all bits = 1 (extend modes) */
+       viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
+       /* line compare should set all bits = 1 (extend modes) */
+       viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
+       /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
+       /* extend mode always set to e3h */
+       viafb_write_reg(CR17, VIACR, 0xe3);
+       /* extend mode always set to 0h */
+       viafb_write_reg(CR08, VIACR, 0x00);
+       /* extend mode always set to 0h */
+       viafb_write_reg(CR14, VIACR, 0x00);
+
+       /* If K8M800, enable Prefetch Mode. */
+       if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
+               || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
+               viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
+       if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+           && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
+               viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
+
+}
+
+void viafb_load_reg(int timing_value, int viafb_load_reg_num,
+       struct io_register *reg,
+             int io_type)
+{
+       int reg_mask;
+       int bit_num = 0;
+       int data;
+       int i, j;
+       int shift_next_reg;
+       int start_index, end_index, cr_index;
+       u16 get_bit;
+
+       for (i = 0; i < viafb_load_reg_num; i++) {
+               reg_mask = 0;
+               data = 0;
+               start_index = reg[i].start_bit;
+               end_index = reg[i].end_bit;
+               cr_index = reg[i].io_addr;
+
+               shift_next_reg = bit_num;
+               for (j = start_index; j <= end_index; j++) {
+                       /*if (bit_num==8) timing_value = timing_value >>8; */
+                       reg_mask = reg_mask | (BIT0 << j);
+                       get_bit = (timing_value & (BIT0 << bit_num));
+                       data =
+                           data | ((get_bit >> shift_next_reg) << start_index);
+                       bit_num++;
+               }
+               if (io_type == VIACR)
+                       viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
+               else
+                       viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
+       }
+
+}
+
+/* Write Registers */
+void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
+{
+       int i;
+       unsigned char RegTemp;
+
+       /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
+
+       for (i = 0; i < ItemNum; i++) {
+               outb(RegTable[i].index, RegTable[i].port);
+               RegTemp = inb(RegTable[i].port + 1);
+               RegTemp = (RegTemp & (~RegTable[i].mask)) | RegTable[i].value;
+               outb(RegTemp, RegTable[i].port + 1);
+       }
+}
+
+void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga)
+{
+       int reg_value;
+       int viafb_load_reg_num;
+       struct io_register *reg;
+
+       switch (set_iga) {
+       case IGA1_IGA2:
+       case IGA1:
+               reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte);
+               viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num;
+               reg = offset_reg.iga1_offset_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+               if (set_iga == IGA1)
+                       break;
+       case IGA2:
+               reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte);
+               viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
+               reg = offset_reg.iga2_offset_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+               break;
+       }
+}
+
+void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
+{
+       int reg_value;
+       int viafb_load_reg_num;
+       struct io_register *reg = NULL;
+
+       switch (set_iga) {
+       case IGA1_IGA2:
+       case IGA1:
+               reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
+               viafb_load_reg_num = fetch_count_reg.
+                       iga1_fetch_count_reg.reg_num;
+               reg = fetch_count_reg.iga1_fetch_count_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+               if (set_iga == IGA1)
+                       break;
+       case IGA2:
+               reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
+               viafb_load_reg_num = fetch_count_reg.
+                       iga2_fetch_count_reg.reg_num;
+               reg = fetch_count_reg.iga2_fetch_count_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+               break;
+       }
+
+}
+
+void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
+{
+       int reg_value;
+       int viafb_load_reg_num;
+       struct io_register *reg = NULL;
+       int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
+           0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
+       int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
+           0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
+
+       if (set_iga == IGA1) {
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
+                       iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           K800_IGA1_FIFO_HIGH_THRESHOLD;
+                       /* If resolution > 1280x1024, expire length = 64, else
+                          expire length = 128 */
+                       if ((hor_active > 1280) && (ver_active > 1024))
+                               iga1_display_queue_expire_num = 16;
+                       else
+                               iga1_display_queue_expire_num =
+                                   K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
+                       iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           P880_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+
+                       /* If resolution > 1280x1024, expire length = 64, else
+                          expire length = 128 */
+                       if ((hor_active > 1280) && (ver_active > 1024))
+                               iga1_display_queue_expire_num = 16;
+                       else
+                               iga1_display_queue_expire_num =
+                                   P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
+                       iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           CN700_IGA1_FIFO_HIGH_THRESHOLD;
+
+                       /* If resolution > 1280x1024, expire length = 64,
+                          else expire length = 128 */
+                       if ((hor_active > 1280) && (ver_active > 1024))
+                               iga1_display_queue_expire_num = 16;
+                       else
+                               iga1_display_queue_expire_num =
+                                   CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+                       iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           CX700_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
+                       iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           K8M890_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
+                       iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           P4M890_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
+                       iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           P4M900_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
+                       iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           VX800_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               /* Set Display FIFO Depath Select */
+               reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
+               viafb_load_reg_num =
+                   display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
+               reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+               /* Set Display FIFO Threshold Select */
+               reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
+               viafb_load_reg_num =
+                   fifo_threshold_select_reg.
+                   iga1_fifo_threshold_select_reg.reg_num;
+               reg =
+                   fifo_threshold_select_reg.
+                   iga1_fifo_threshold_select_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+               /* Set FIFO High Threshold Select */
+               reg_value =
+                   IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
+               viafb_load_reg_num =
+                   fifo_high_threshold_select_reg.
+                   iga1_fifo_high_threshold_select_reg.reg_num;
+               reg =
+                   fifo_high_threshold_select_reg.
+                   iga1_fifo_high_threshold_select_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+               /* Set Display Queue Expire Num */
+               reg_value =
+                   IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
+                   (iga1_display_queue_expire_num);
+               viafb_load_reg_num =
+                   display_queue_expire_num_reg.
+                   iga1_display_queue_expire_num_reg.reg_num;
+               reg =
+                   display_queue_expire_num_reg.
+                   iga1_display_queue_expire_num_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+       } else {
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
+                       iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           K800_IGA2_FIFO_HIGH_THRESHOLD;
+
+                       /* If resolution > 1280x1024, expire length = 64,
+                          else  expire length = 128 */
+                       if ((hor_active > 1280) && (ver_active > 1024))
+                               iga2_display_queue_expire_num = 16;
+                       else
+                               iga2_display_queue_expire_num =
+                                   K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
+                       iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           P880_IGA2_FIFO_HIGH_THRESHOLD;
+
+                       /* If resolution > 1280x1024, expire length = 64,
+                          else  expire length = 128 */
+                       if ((hor_active > 1280) && (ver_active > 1024))
+                               iga2_display_queue_expire_num = 16;
+                       else
+                               iga2_display_queue_expire_num =
+                                   P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
+                       iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           CN700_IGA2_FIFO_HIGH_THRESHOLD;
+
+                       /* If resolution > 1280x1024, expire length = 64,
+                          else expire length = 128 */
+                       if ((hor_active > 1280) && (ver_active > 1024))
+                               iga2_display_queue_expire_num = 16;
+                       else
+                               iga2_display_queue_expire_num =
+                                   CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+                       iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           CX700_IGA2_FIFO_HIGH_THRESHOLD;
+                       iga2_display_queue_expire_num =
+                           CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
+                       iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           K8M890_IGA2_FIFO_HIGH_THRESHOLD;
+                       iga2_display_queue_expire_num =
+                           K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
+                       iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           P4M890_IGA2_FIFO_HIGH_THRESHOLD;
+                       iga2_display_queue_expire_num =
+                           P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
+                       iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           P4M900_IGA2_FIFO_HIGH_THRESHOLD;
+                       iga2_display_queue_expire_num =
+                           P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
+                       iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           VX800_IGA2_FIFO_HIGH_THRESHOLD;
+                       iga2_display_queue_expire_num =
+                           VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
+                       /* Set Display FIFO Depath Select */
+                       reg_value =
+                           IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
+                           - 1;
+                       /* Patch LCD in IGA2 case */
+                       viafb_load_reg_num =
+                           display_fifo_depth_reg.
+                           iga2_fifo_depth_select_reg.reg_num;
+                       reg =
+                           display_fifo_depth_reg.
+                           iga2_fifo_depth_select_reg.reg;
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_num, reg, VIACR);
+               } else {
+
+                       /* Set Display FIFO Depath Select */
+                       reg_value =
+                           IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
+                       viafb_load_reg_num =
+                           display_fifo_depth_reg.
+                           iga2_fifo_depth_select_reg.reg_num;
+                       reg =
+                           display_fifo_depth_reg.
+                           iga2_fifo_depth_select_reg.reg;
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_num, reg, VIACR);
+               }
+
+               /* Set Display FIFO Threshold Select */
+               reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
+               viafb_load_reg_num =
+                   fifo_threshold_select_reg.
+                   iga2_fifo_threshold_select_reg.reg_num;
+               reg =
+                   fifo_threshold_select_reg.
+                   iga2_fifo_threshold_select_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+
+               /* Set FIFO High Threshold Select */
+               reg_value =
+                   IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
+               viafb_load_reg_num =
+                   fifo_high_threshold_select_reg.
+                   iga2_fifo_high_threshold_select_reg.reg_num;
+               reg =
+                   fifo_high_threshold_select_reg.
+                   iga2_fifo_high_threshold_select_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+
+               /* Set Display Queue Expire Num */
+               reg_value =
+                   IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
+                   (iga2_display_queue_expire_num);
+               viafb_load_reg_num =
+                   display_queue_expire_num_reg.
+                   iga2_display_queue_expire_num_reg.reg_num;
+               reg =
+                   display_queue_expire_num_reg.
+                   iga2_display_queue_expire_num_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+
+       }
+
+}
+
+u32 viafb_get_clk_value(int clk)
+{
+       int i;
+
+       for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) {
+               if (clk == pll_value[i].clk) {
+                       switch (viaparinfo->chip_info->gfx_chip_name) {
+                       case UNICHROME_CLE266:
+                       case UNICHROME_K400:
+                               return pll_value[i].cle266_pll;
+
+                       case UNICHROME_K800:
+                       case UNICHROME_PM800:
+                       case UNICHROME_CN700:
+                               return pll_value[i].k800_pll;
+
+                       case UNICHROME_CX700:
+                       case UNICHROME_K8M890:
+                       case UNICHROME_P4M890:
+                       case UNICHROME_P4M900:
+                       case UNICHROME_VX800:
+                               return pll_value[i].cx700_pll;
+                       }
+               }
+       }
+
+       DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n");
+       return 0;
+}
+
+/* Set VCLK*/
+void viafb_set_vclock(u32 CLK, int set_iga)
+{
+       unsigned char RegTemp;
+
+       /* H.W. Reset : ON */
+       viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+
+       if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+               /* Change D,N FOR VCLK */
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CLE266:
+               case UNICHROME_K400:
+                       viafb_write_reg(SR46, VIASR, CLK / 0x100);
+                       viafb_write_reg(SR47, VIASR, CLK % 0x100);
+                       break;
+
+               case UNICHROME_K800:
+               case UNICHROME_PM800:
+               case UNICHROME_CN700:
+               case UNICHROME_CX700:
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M890:
+               case UNICHROME_P4M900:
+               case UNICHROME_VX800:
+                       viafb_write_reg(SR44, VIASR, CLK / 0x10000);
+                       DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000);
+                       viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100);
+                       DEBUG_MSG(KERN_INFO "\nSR45=%x",
+                                 (CLK & 0xFFFF) / 0x100);
+                       viafb_write_reg(SR46, VIASR, CLK % 0x100);
+                       DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100);
+                       break;
+               }
+       }
+
+       if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+               /* Change D,N FOR LCK */
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CLE266:
+               case UNICHROME_K400:
+                       viafb_write_reg(SR44, VIASR, CLK / 0x100);
+                       viafb_write_reg(SR45, VIASR, CLK % 0x100);
+                       break;
+
+               case UNICHROME_K800:
+               case UNICHROME_PM800:
+               case UNICHROME_CN700:
+               case UNICHROME_CX700:
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M890:
+               case UNICHROME_P4M900:
+               case UNICHROME_VX800:
+                       viafb_write_reg(SR4A, VIASR, CLK / 0x10000);
+                       viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100);
+                       viafb_write_reg(SR4C, VIASR, CLK % 0x100);
+                       break;
+               }
+       }
+
+       /* H.W. Reset : OFF */
+       viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+
+       /* Reset PLL */
+       if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+               viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
+               viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
+       }
+
+       if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+               viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
+               viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
+       }
+
+       /* Fire! */
+       RegTemp = inb(VIARMisc);
+       outb(RegTemp | (BIT2 + BIT3), VIAWMisc);
+}
+
+void viafb_load_crtc_timing(struct display_timing device_timing,
+       int set_iga)
+{
+       int i;
+       int viafb_load_reg_num = 0;
+       int reg_value = 0;
+       struct io_register *reg = NULL;
+
+       viafb_unlock_crt();
+
+       for (i = 0; i < 12; i++) {
+               if (set_iga == IGA1) {
+                       switch (i) {
+                       case H_TOTAL_INDEX:
+                               reg_value =
+                                   IGA1_HOR_TOTAL_FORMULA(device_timing.
+                                                          hor_total);
+                               viafb_load_reg_num =
+                                       iga1_crtc_reg.hor_total.reg_num;
+                               reg = iga1_crtc_reg.hor_total.reg;
+                               break;
+                       case H_ADDR_INDEX:
+                               reg_value =
+                                   IGA1_HOR_ADDR_FORMULA(device_timing.
+                                                         hor_addr);
+                               viafb_load_reg_num =
+                                       iga1_crtc_reg.hor_addr.reg_num;
+                               reg = iga1_crtc_reg.hor_addr.reg;
+                               break;
+                       case H_BLANK_START_INDEX:
+                               reg_value =
+                                   IGA1_HOR_BLANK_START_FORMULA
+                                   (device_timing.hor_blank_start);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.hor_blank_start.reg_num;
+                               reg = iga1_crtc_reg.hor_blank_start.reg;
+                               break;
+                       case H_BLANK_END_INDEX:
+                               reg_value =
+                                   IGA1_HOR_BLANK_END_FORMULA
+                                   (device_timing.hor_blank_start,
+                                    device_timing.hor_blank_end);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.hor_blank_end.reg_num;
+                               reg = iga1_crtc_reg.hor_blank_end.reg;
+                               break;
+                       case H_SYNC_START_INDEX:
+                               reg_value =
+                                   IGA1_HOR_SYNC_START_FORMULA
+                                   (device_timing.hor_sync_start);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.hor_sync_start.reg_num;
+                               reg = iga1_crtc_reg.hor_sync_start.reg;
+                               break;
+                       case H_SYNC_END_INDEX:
+                               reg_value =
+                                   IGA1_HOR_SYNC_END_FORMULA
+                                   (device_timing.hor_sync_start,
+                                    device_timing.hor_sync_end);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.hor_sync_end.reg_num;
+                               reg = iga1_crtc_reg.hor_sync_end.reg;
+                               break;
+                       case V_TOTAL_INDEX:
+                               reg_value =
+                                   IGA1_VER_TOTAL_FORMULA(device_timing.
+                                                          ver_total);
+                               viafb_load_reg_num =
+                                       iga1_crtc_reg.ver_total.reg_num;
+                               reg = iga1_crtc_reg.ver_total.reg;
+                               break;
+                       case V_ADDR_INDEX:
+                               reg_value =
+                                   IGA1_VER_ADDR_FORMULA(device_timing.
+                                                         ver_addr);
+                               viafb_load_reg_num =
+                                       iga1_crtc_reg.ver_addr.reg_num;
+                               reg = iga1_crtc_reg.ver_addr.reg;
+                               break;
+                       case V_BLANK_START_INDEX:
+                               reg_value =
+                                   IGA1_VER_BLANK_START_FORMULA
+                                   (device_timing.ver_blank_start);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.ver_blank_start.reg_num;
+                               reg = iga1_crtc_reg.ver_blank_start.reg;
+                               break;
+                       case V_BLANK_END_INDEX:
+                               reg_value =
+                                   IGA1_VER_BLANK_END_FORMULA
+                                   (device_timing.ver_blank_start,
+                                    device_timing.ver_blank_end);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.ver_blank_end.reg_num;
+                               reg = iga1_crtc_reg.ver_blank_end.reg;
+                               break;
+                       case V_SYNC_START_INDEX:
+                               reg_value =
+                                   IGA1_VER_SYNC_START_FORMULA
+                                   (device_timing.ver_sync_start);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.ver_sync_start.reg_num;
+                               reg = iga1_crtc_reg.ver_sync_start.reg;
+                               break;
+                       case V_SYNC_END_INDEX:
+                               reg_value =
+                                   IGA1_VER_SYNC_END_FORMULA
+                                   (device_timing.ver_sync_start,
+                                    device_timing.ver_sync_end);
+                               viafb_load_reg_num =
+                                   iga1_crtc_reg.ver_sync_end.reg_num;
+                               reg = iga1_crtc_reg.ver_sync_end.reg;
+                               break;
+
+                       }
+               }
+
+               if (set_iga == IGA2) {
+                       switch (i) {
+                       case H_TOTAL_INDEX:
+                               reg_value =
+                                   IGA2_HOR_TOTAL_FORMULA(device_timing.
+                                                          hor_total);
+                               viafb_load_reg_num =
+                                       iga2_crtc_reg.hor_total.reg_num;
+                               reg = iga2_crtc_reg.hor_total.reg;
+                               break;
+                       case H_ADDR_INDEX:
+                               reg_value =
+                                   IGA2_HOR_ADDR_FORMULA(device_timing.
+                                                         hor_addr);
+                               viafb_load_reg_num =
+                                       iga2_crtc_reg.hor_addr.reg_num;
+                               reg = iga2_crtc_reg.hor_addr.reg;
+                               break;
+                       case H_BLANK_START_INDEX:
+                               reg_value =
+                                   IGA2_HOR_BLANK_START_FORMULA
+                                   (device_timing.hor_blank_start);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.hor_blank_start.reg_num;
+                               reg = iga2_crtc_reg.hor_blank_start.reg;
+                               break;
+                       case H_BLANK_END_INDEX:
+                               reg_value =
+                                   IGA2_HOR_BLANK_END_FORMULA
+                                   (device_timing.hor_blank_start,
+                                    device_timing.hor_blank_end);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.hor_blank_end.reg_num;
+                               reg = iga2_crtc_reg.hor_blank_end.reg;
+                               break;
+                       case H_SYNC_START_INDEX:
+                               reg_value =
+                                   IGA2_HOR_SYNC_START_FORMULA
+                                   (device_timing.hor_sync_start);
+                               if (UNICHROME_CN700 <=
+                                       viaparinfo->chip_info->gfx_chip_name)
+                                       viafb_load_reg_num =
+                                           iga2_crtc_reg.hor_sync_start.
+                                           reg_num;
+                               else
+                                       viafb_load_reg_num = 3;
+                               reg = iga2_crtc_reg.hor_sync_start.reg;
+                               break;
+                       case H_SYNC_END_INDEX:
+                               reg_value =
+                                   IGA2_HOR_SYNC_END_FORMULA
+                                   (device_timing.hor_sync_start,
+                                    device_timing.hor_sync_end);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.hor_sync_end.reg_num;
+                               reg = iga2_crtc_reg.hor_sync_end.reg;
+                               break;
+                       case V_TOTAL_INDEX:
+                               reg_value =
+                                   IGA2_VER_TOTAL_FORMULA(device_timing.
+                                                          ver_total);
+                               viafb_load_reg_num =
+                                       iga2_crtc_reg.ver_total.reg_num;
+                               reg = iga2_crtc_reg.ver_total.reg;
+                               break;
+                       case V_ADDR_INDEX:
+                               reg_value =
+                                   IGA2_VER_ADDR_FORMULA(device_timing.
+                                                         ver_addr);
+                               viafb_load_reg_num =
+                                       iga2_crtc_reg.ver_addr.reg_num;
+                               reg = iga2_crtc_reg.ver_addr.reg;
+                               break;
+                       case V_BLANK_START_INDEX:
+                               reg_value =
+                                   IGA2_VER_BLANK_START_FORMULA
+                                   (device_timing.ver_blank_start);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.ver_blank_start.reg_num;
+                               reg = iga2_crtc_reg.ver_blank_start.reg;
+                               break;
+                       case V_BLANK_END_INDEX:
+                               reg_value =
+                                   IGA2_VER_BLANK_END_FORMULA
+                                   (device_timing.ver_blank_start,
+                                    device_timing.ver_blank_end);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.ver_blank_end.reg_num;
+                               reg = iga2_crtc_reg.ver_blank_end.reg;
+                               break;
+                       case V_SYNC_START_INDEX:
+                               reg_value =
+                                   IGA2_VER_SYNC_START_FORMULA
+                                   (device_timing.ver_sync_start);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.ver_sync_start.reg_num;
+                               reg = iga2_crtc_reg.ver_sync_start.reg;
+                               break;
+                       case V_SYNC_END_INDEX:
+                               reg_value =
+                                   IGA2_VER_SYNC_END_FORMULA
+                                   (device_timing.ver_sync_start,
+                                    device_timing.ver_sync_end);
+                               viafb_load_reg_num =
+                                   iga2_crtc_reg.ver_sync_end.reg_num;
+                               reg = iga2_crtc_reg.ver_sync_end.reg;
+                               break;
+
+                       }
+               }
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+       }
+
+       viafb_lock_crt();
+}
+
+void viafb_set_color_depth(int bpp_byte, int set_iga)
+{
+       if (set_iga == IGA1) {
+               switch (bpp_byte) {
+               case MODE_8BPP:
+                       viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E);
+                       break;
+               case MODE_16BPP:
+                       viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE);
+                       break;
+               case MODE_32BPP:
+                       viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE);
+                       break;
+               }
+       } else {
+               switch (bpp_byte) {
+               case MODE_8BPP:
+                       viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7);
+                       break;
+               case MODE_16BPP:
+                       viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7);
+                       break;
+               case MODE_32BPP:
+                       viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7);
+                       break;
+               }
+       }
+}
+
+void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
+       int mode_index, int bpp_byte, int set_iga)
+{
+       struct VideoModeTable *video_mode;
+       struct display_timing crt_reg;
+       int i;
+       int index = 0;
+       int h_addr, v_addr;
+       u32 pll_D_N;
+
+       video_mode = &CLE266Modes[search_mode_setting(mode_index)];
+
+       for (i = 0; i < video_mode->mode_array; i++) {
+               index = i;
+
+               if (crt_table[i].refresh_rate == viaparinfo->
+                       crt_setting_info->refresh_rate)
+                       break;
+       }
+
+       crt_reg = crt_table[index].crtc;
+
+       /* Mode 640x480 has border, but LCD/DFP didn't have border. */
+       /* So we would delete border. */
+       if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480)
+           && (viaparinfo->crt_setting_info->refresh_rate == 60)) {
+               /* The border is 8 pixels. */
+               crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
+
+               /* Blanking time should add left and right borders. */
+               crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
+       }
+
+       h_addr = crt_reg.hor_addr;
+       v_addr = crt_reg.ver_addr;
+
+       /* update polarity for CRT timing */
+       if (crt_table[index].h_sync_polarity == NEGATIVE) {
+               if (crt_table[index].v_sync_polarity == NEGATIVE)
+                       outb((inb(VIARMisc) & (~(BIT6 + BIT7))) |
+                            (BIT6 + BIT7), VIAWMisc);
+               else
+                       outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT6),
+                            VIAWMisc);
+       } else {
+               if (crt_table[index].v_sync_polarity == NEGATIVE)
+                       outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT7),
+                            VIAWMisc);
+               else
+                       outb((inb(VIARMisc) & (~(BIT6 + BIT7))), VIAWMisc);
+       }
+
+       if (set_iga == IGA1) {
+               viafb_unlock_crt();
+               viafb_write_reg(CR09, VIACR, 0x00);     /*initial CR09=0 */
+               viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
+               viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+       }
+
+       switch (set_iga) {
+       case IGA1:
+               viafb_load_crtc_timing(crt_reg, IGA1);
+               break;
+       case IGA2:
+               viafb_load_crtc_timing(crt_reg, IGA2);
+               break;
+       }
+
+       load_fix_bit_crtc_reg();
+       viafb_lock_crt();
+       viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+       viafb_load_offset_reg(h_addr, bpp_byte, set_iga);
+       viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
+
+       /* load FIFO */
+       if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+           && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
+               viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
+
+       /* load SR Register About Memory and Color part */
+       viafb_set_color_depth(bpp_byte, set_iga);
+
+       pll_D_N = viafb_get_clk_value(crt_table[index].clk);
+       DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
+       viafb_set_vclock(pll_D_N, set_iga);
+
+}
+
+void viafb_init_chip_info(void)
+{
+       init_gfx_chip_info();
+       init_tmds_chip_info();
+       init_lvds_chip_info();
+
+       viaparinfo->crt_setting_info->iga_path = IGA1;
+       viaparinfo->crt_setting_info->refresh_rate = viafb_refresh;
+
+       /*Set IGA path for each device */
+       viafb_set_iga_path();
+
+       viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
+       viaparinfo->lvds_setting_info->get_lcd_size_method =
+               GET_LCD_SIZE_BY_USER_SETTING;
+       viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
+       viaparinfo->lvds_setting_info2->display_method =
+               viaparinfo->lvds_setting_info->display_method;
+       viaparinfo->lvds_setting_info2->lcd_mode =
+               viaparinfo->lvds_setting_info->lcd_mode;
+}
+
+void viafb_update_device_setting(int hres, int vres,
+       int bpp, int vmode_refresh, int flag)
+{
+       if (flag == 0) {
+               viaparinfo->crt_setting_info->h_active = hres;
+               viaparinfo->crt_setting_info->v_active = vres;
+               viaparinfo->crt_setting_info->bpp = bpp;
+               viaparinfo->crt_setting_info->refresh_rate =
+                       vmode_refresh;
+
+               viaparinfo->tmds_setting_info->h_active = hres;
+               viaparinfo->tmds_setting_info->v_active = vres;
+               viaparinfo->tmds_setting_info->bpp = bpp;
+               viaparinfo->tmds_setting_info->refresh_rate =
+                       vmode_refresh;
+
+               viaparinfo->lvds_setting_info->h_active = hres;
+               viaparinfo->lvds_setting_info->v_active = vres;
+               viaparinfo->lvds_setting_info->bpp = bpp;
+               viaparinfo->lvds_setting_info->refresh_rate =
+                       vmode_refresh;
+               viaparinfo->lvds_setting_info2->h_active = hres;
+               viaparinfo->lvds_setting_info2->v_active = vres;
+               viaparinfo->lvds_setting_info2->bpp = bpp;
+               viaparinfo->lvds_setting_info2->refresh_rate =
+                       vmode_refresh;
+       } else {
+
+               if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
+                       viaparinfo->tmds_setting_info->h_active = hres;
+                       viaparinfo->tmds_setting_info->v_active = vres;
+                       viaparinfo->tmds_setting_info->bpp = bpp;
+                       viaparinfo->tmds_setting_info->refresh_rate =
+                               vmode_refresh;
+               }
+
+               if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
+                       viaparinfo->lvds_setting_info->h_active = hres;
+                       viaparinfo->lvds_setting_info->v_active = vres;
+                       viaparinfo->lvds_setting_info->bpp = bpp;
+                       viaparinfo->lvds_setting_info->refresh_rate =
+                               vmode_refresh;
+               }
+               if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
+                       viaparinfo->lvds_setting_info2->h_active = hres;
+                       viaparinfo->lvds_setting_info2->v_active = vres;
+                       viaparinfo->lvds_setting_info2->bpp = bpp;
+                       viaparinfo->lvds_setting_info2->refresh_rate =
+                               vmode_refresh;
+               }
+       }
+}
+
+static void init_gfx_chip_info(void)
+{
+       struct pci_dev *pdev = NULL;
+       u32 i;
+       u8 tmp;
+
+       /* Indentify GFX Chip Name */
+       for (i = 0; pciidlist[i].vendor != 0; i++) {
+               pdev = pci_get_device(pciidlist[i].vendor,
+                       pciidlist[i].device, 0);
+               if (pdev)
+                       break;
+       }
+
+       if (!pciidlist[i].vendor)
+               return ;
+
+       viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index;
+
+       /* Check revision of CLE266 Chip */
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+               /* CR4F only define in CLE266.CX chip */
+               tmp = viafb_read_reg(VIACR, CR4F);
+               viafb_write_reg(CR4F, VIACR, 0x55);
+               if (viafb_read_reg(VIACR, CR4F) != 0x55)
+                       viaparinfo->chip_info->gfx_chip_revision =
+                       CLE266_REVISION_AX;
+               else
+                       viaparinfo->chip_info->gfx_chip_revision =
+                       CLE266_REVISION_CX;
+               /* restore orignal CR4F value */
+               viafb_write_reg(CR4F, VIACR, tmp);
+       }
+
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+               tmp = viafb_read_reg(VIASR, SR43);
+               DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
+               if (tmp & 0x02) {
+                       viaparinfo->chip_info->gfx_chip_revision =
+                               CX700_REVISION_700M2;
+               } else if (tmp & 0x40) {
+                       viaparinfo->chip_info->gfx_chip_revision =
+                               CX700_REVISION_700M;
+               } else {
+                       viaparinfo->chip_info->gfx_chip_revision =
+                               CX700_REVISION_700;
+               }
+       }
+
+       pci_dev_put(pdev);
+}
+
+static void init_tmds_chip_info(void)
+{
+       viafb_tmds_trasmitter_identify();
+
+       if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
+               output_interface) {
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CX700:
+                       {
+                               /* we should check support by hardware layout.*/
+                               if ((viafb_display_hardware_layout ==
+                                    HW_LAYOUT_DVI_ONLY)
+                                   || (viafb_display_hardware_layout ==
+                                       HW_LAYOUT_LCD_DVI)) {
+                                       viaparinfo->chip_info->tmds_chip_info.
+                                           output_interface = INTERFACE_TMDS;
+                               } else {
+                                       viaparinfo->chip_info->tmds_chip_info.
+                                               output_interface =
+                                               INTERFACE_NONE;
+                               }
+                               break;
+                       }
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M900:
+               case UNICHROME_P4M890:
+                       /* TMDS on PCIE, we set DFPLOW as default. */
+                       viaparinfo->chip_info->tmds_chip_info.output_interface =
+                           INTERFACE_DFP_LOW;
+                       break;
+               default:
+                       {
+                               /* set DVP1 default for DVI */
+                               viaparinfo->chip_info->tmds_chip_info
+                               .output_interface = INTERFACE_DVP1;
+                       }
+               }
+       }
+
+       DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
+                 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
+       viaparinfo->tmds_setting_info->get_dvi_size_method =
+               GET_DVI_SIZE_BY_VGA_BIOS;
+       viafb_init_dvi_size();
+}
+
+static void init_lvds_chip_info(void)
+{
+       if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM)
+               viaparinfo->lvds_setting_info->get_lcd_size_method =
+                   GET_LCD_SIZE_BY_VGA_BIOS;
+       else
+               viaparinfo->lvds_setting_info->get_lcd_size_method =
+                   GET_LCD_SIZE_BY_USER_SETTING;
+
+       viafb_lvds_trasmitter_identify();
+       viafb_init_lcd_size();
+       viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
+                                  viaparinfo->lvds_setting_info);
+       if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+               viafb_init_lvds_output_interface(&viaparinfo->chip_info->
+                       lvds_chip_info2, viaparinfo->lvds_setting_info2);
+       }
+       /*If CX700,two singel LCD, we need to reassign
+          LCD interface to different LVDS port */
+       if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
+           && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
+               if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
+                       lvds_chip_name) && (INTEGRATED_LVDS ==
+                       viaparinfo->chip_info->
+                       lvds_chip_info2.lvds_chip_name)) {
+                       viaparinfo->chip_info->lvds_chip_info.output_interface =
+                               INTERFACE_LVDS0;
+                       viaparinfo->chip_info->lvds_chip_info2.
+                               output_interface =
+                           INTERFACE_LVDS1;
+               }
+       }
+
+       DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
+                 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
+       DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
+                 viaparinfo->chip_info->lvds_chip_info.output_interface);
+       DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
+                 viaparinfo->chip_info->lvds_chip_info.output_interface);
+}
+
+void viafb_init_dac(int set_iga)
+{
+       int i;
+       u8 tmp;
+
+       if (set_iga == IGA1) {
+               /* access Primary Display's LUT */
+               viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
+               /* turn off LCK */
+               viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
+               for (i = 0; i < 256; i++) {
+                       write_dac_reg(i, palLUT_table[i].red,
+                                     palLUT_table[i].green,
+                                     palLUT_table[i].blue);
+               }
+               /* turn on LCK */
+               viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
+       } else {
+               tmp = viafb_read_reg(VIACR, CR6A);
+               /* access Secondary Display's LUT */
+               viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
+               viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
+               for (i = 0; i < 256; i++) {
+                       write_dac_reg(i, palLUT_table[i].red,
+                                     palLUT_table[i].green,
+                                     palLUT_table[i].blue);
+               }
+               /* set IGA1 DAC for default */
+               viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
+               viafb_write_reg(CR6A, VIACR, tmp);
+       }
+}
+
+static void device_screen_off(void)
+{
+       /* turn off CRT screen (IGA1) */
+       viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
+}
+
+static void device_screen_on(void)
+{
+       /* turn on CRT screen (IGA1) */
+       viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
+}
+
+static void set_display_channel(void)
+{
+       /*If viafb_LCD2_ON, on cx700, internal lvds's information
+       is keeped on lvds_setting_info2 */
+       if (viafb_LCD2_ON &&
+               viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
+               /* For dual channel LCD: */
+               /* Set to Dual LVDS channel. */
+               viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
+       } else if (viafb_LCD_ON && viafb_DVI_ON) {
+               /* For LCD+DFP: */
+               /* Set to LVDS1 + TMDS channel. */
+               viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
+       } else if (viafb_DVI_ON) {
+               /* Set to single TMDS channel. */
+               viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
+       } else if (viafb_LCD_ON) {
+               if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
+                       /* For dual channel LCD: */
+                       /* Set to Dual LVDS channel. */
+                       viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
+               } else {
+                       /* Set to LVDS0 + LVDS1 channel. */
+                       viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
+               }
+       }
+}
+
+int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
+       int vmode_index1, int hor_res1, int ver_res1, int video_bpp1)
+{
+       int i, j;
+       int port;
+       u8 value, index, mask;
+       struct VideoModeTable *vmode_tbl;
+       struct crt_mode_table *crt_timing;
+       struct VideoModeTable *vmode_tbl1 = NULL;
+       struct crt_mode_table *crt_timing1 = NULL;
+
+       DEBUG_MSG(KERN_INFO "Set Mode!!\n");
+       DEBUG_MSG(KERN_INFO
+                 "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
+                 vmode_index, hor_res, ver_res, video_bpp);
+
+       device_screen_off();
+       vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)];
+       crt_timing = vmode_tbl->crtc;
+
+       if (viafb_SAMM_ON == 1) {
+               vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)];
+               crt_timing1 = vmode_tbl1->crtc;
+       }
+
+       inb(VIAStatus);
+       outb(0x00, VIAAR);
+
+       /* Write Common Setting for Video Mode */
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_CLE266:
+               viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
+               break;
+
+       case UNICHROME_K400:
+               viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
+               break;
+
+       case UNICHROME_K800:
+       case UNICHROME_PM800:
+               viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
+               break;
+
+       case UNICHROME_CN700:
+       case UNICHROME_K8M890:
+       case UNICHROME_P4M890:
+       case UNICHROME_P4M900:
+               viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
+               break;
+
+       case UNICHROME_CX700:
+               viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
+
+       case UNICHROME_VX800:
+               viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs);
+
+               break;
+       }
+
+       device_off();
+
+       /* Fill VPIT Parameters */
+       /* Write Misc Register */
+       outb(VPIT.Misc, VIAWMisc);
+
+       /* Write Sequencer */
+       for (i = 1; i <= StdSR; i++) {
+               outb(i, VIASR);
+               outb(VPIT.SR[i - 1], VIASR + 1);
+       }
+
+       viafb_set_start_addr();
+       viafb_set_iga_path();
+
+       /* Write CRTC */
+       viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1);
+
+       /* Write Graphic Controller */
+       for (i = 0; i < StdGR; i++) {
+               outb(i, VIAGR);
+               outb(VPIT.GR[i], VIAGR + 1);
+       }
+
+       /* Write Attribute Controller */
+       for (i = 0; i < StdAR; i++) {
+               inb(VIAStatus);
+               outb(i, VIAAR);
+               outb(VPIT.AR[i], VIAAR);
+       }
+
+       inb(VIAStatus);
+       outb(0x20, VIAAR);
+
+       /* Update Patch Register */
+
+       if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+           || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) {
+               for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
+                       if (res_patch_table[i].mode_index == vmode_index) {
+                               for (j = 0;
+                                    j < res_patch_table[i].table_length; j++) {
+                                       index =
+                                           res_patch_table[i].
+                                           io_reg_table[j].index;
+                                       port =
+                                           res_patch_table[i].
+                                           io_reg_table[j].port;
+                                       value =
+                                           res_patch_table[i].
+                                           io_reg_table[j].value;
+                                       mask =
+                                           res_patch_table[i].
+                                           io_reg_table[j].mask;
+                                       viafb_write_reg_mask(index, port, value,
+                                                      mask);
+                               }
+                       }
+               }
+       }
+
+       if (viafb_SAMM_ON == 1) {
+               if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+                   || (viaparinfo->chip_info->gfx_chip_name ==
+                   UNICHROME_K400)) {
+                       for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
+                               if (res_patch_table[i].mode_index ==
+                                   vmode_index1) {
+                                       for (j = 0;
+                                            j <
+                                            res_patch_table[i].
+                                            table_length; j++) {
+                                               index =
+                                                   res_patch_table[i].
+                                                   io_reg_table[j].index;
+                                               port =
+                                                   res_patch_table[i].
+                                                   io_reg_table[j].port;
+                                               value =
+                                                   res_patch_table[i].
+                                                   io_reg_table[j].value;
+                                               mask =
+                                                   res_patch_table[i].
+                                                   io_reg_table[j].mask;
+                                               viafb_write_reg_mask(index,
+                                                       port, value, mask);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* Update Refresh Rate Setting */
+
+       /* Clear On Screen */
+
+       /* CRT set mode */
+       if (viafb_CRT_ON) {
+               if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
+                       IGA2)) {
+                       viafb_fill_crtc_timing(crt_timing1, vmode_index1,
+                               video_bpp1 / 8,
+                               viaparinfo->crt_setting_info->iga_path);
+               } else {
+                       viafb_fill_crtc_timing(crt_timing, vmode_index,
+                               video_bpp / 8,
+                               viaparinfo->crt_setting_info->iga_path);
+               }
+
+               set_crt_output_path(viaparinfo->crt_setting_info->iga_path);
+
+               /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
+               to 8 alignment (1368),there is several pixels (2 pixels)
+               on right side of screen. */
+               if (hor_res % 8) {
+                       viafb_unlock_crt();
+                       viafb_write_reg(CR02, VIACR,
+                               viafb_read_reg(VIACR, CR02) - 1);
+                       viafb_lock_crt();
+               }
+       }
+
+       if (viafb_DVI_ON) {
+               if (viafb_SAMM_ON &&
+                       (viaparinfo->tmds_setting_info->iga_path == IGA2)) {
+                       viafb_dvi_set_mode(viafb_get_mode_index
+                                    (viaparinfo->tmds_setting_info->h_active,
+                                     viaparinfo->tmds_setting_info->
+                                     v_active, 1),
+                                    video_bpp1, viaparinfo->
+                                    tmds_setting_info->iga_path);
+               } else {
+                       viafb_dvi_set_mode(viafb_get_mode_index
+                                    (viaparinfo->tmds_setting_info->h_active,
+                                     viaparinfo->
+                                     tmds_setting_info->v_active, 0),
+                                    video_bpp, viaparinfo->
+                                    tmds_setting_info->iga_path);
+               }
+       }
+
+       if (viafb_LCD_ON) {
+               if (viafb_SAMM_ON &&
+                       (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
+                       viaparinfo->lvds_setting_info->bpp = video_bpp1;
+                       viafb_lcd_set_mode(crt_timing1, viaparinfo->
+                               lvds_setting_info,
+                                    &viaparinfo->chip_info->lvds_chip_info);
+               } else {
+                       /* IGA1 doesn't have LCD scaling, so set it center. */
+                       if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
+                               viaparinfo->lvds_setting_info->display_method =
+                                   LCD_CENTERING;
+                       }
+                       viaparinfo->lvds_setting_info->bpp = video_bpp;
+                       viafb_lcd_set_mode(crt_timing, viaparinfo->
+                               lvds_setting_info,
+                                    &viaparinfo->chip_info->lvds_chip_info);
+               }
+       }
+       if (viafb_LCD2_ON) {
+               if (viafb_SAMM_ON &&
+                       (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
+                       viaparinfo->lvds_setting_info2->bpp = video_bpp1;
+                       viafb_lcd_set_mode(crt_timing1, viaparinfo->
+                               lvds_setting_info2,
+                                    &viaparinfo->chip_info->lvds_chip_info2);
+               } else {
+                       /* IGA1 doesn't have LCD scaling, so set it center. */
+                       if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
+                               viaparinfo->lvds_setting_info2->display_method =
+                                   LCD_CENTERING;
+                       }
+                       viaparinfo->lvds_setting_info2->bpp = video_bpp;
+                       viafb_lcd_set_mode(crt_timing, viaparinfo->
+                               lvds_setting_info2,
+                                    &viaparinfo->chip_info->lvds_chip_info2);
+               }
+       }
+
+       if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
+           && (viafb_LCD_ON || viafb_DVI_ON))
+               set_display_channel();
+
+       /* If set mode normally, save resolution information for hot-plug . */
+       if (!viafb_hotplug) {
+               viafb_hotplug_Xres = hor_res;
+               viafb_hotplug_Yres = ver_res;
+               viafb_hotplug_bpp = video_bpp;
+               viafb_hotplug_refresh = viafb_refresh;
+
+               if (viafb_DVI_ON)
+                       viafb_DeviceStatus = DVI_Device;
+               else
+                       viafb_DeviceStatus = CRT_Device;
+       }
+       device_on();
+
+       if (viafb_SAMM_ON == 1)
+               viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
+
+       device_screen_on();
+       return 1;
+}
+
+int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
+{
+       int i;
+
+       for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
+               if ((hres == res_map_refresh_tbl[i].hres)
+                   && (vres == res_map_refresh_tbl[i].vres)
+                   && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh))
+                       return res_map_refresh_tbl[i].pixclock;
+       }
+       return RES_640X480_60HZ_PIXCLOCK;
+
+}
+
+int viafb_get_refresh(int hres, int vres, u32 long_refresh)
+{
+#define REFRESH_TOLERANCE 3
+       int i, nearest = -1, diff = REFRESH_TOLERANCE;
+       for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
+               if ((hres == res_map_refresh_tbl[i].hres)
+                   && (vres == res_map_refresh_tbl[i].vres)
+                   && (diff > (abs(long_refresh -
+                   res_map_refresh_tbl[i].vmode_refresh)))) {
+                       diff = abs(long_refresh - res_map_refresh_tbl[i].
+                               vmode_refresh);
+                       nearest = i;
+               }
+       }
+#undef REFRESH_TOLERANCE
+       if (nearest > 0)
+               return res_map_refresh_tbl[nearest].vmode_refresh;
+       return 60;
+}
+
+static void device_off(void)
+{
+       viafb_crt_disable();
+       viafb_dvi_disable();
+       viafb_lcd_disable();
+}
+
+static void device_on(void)
+{
+       if (viafb_CRT_ON == 1)
+               viafb_crt_enable();
+       if (viafb_DVI_ON == 1)
+               viafb_dvi_enable();
+       if (viafb_LCD_ON == 1)
+               viafb_lcd_enable();
+}
+
+void viafb_crt_disable(void)
+{
+       viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4);
+}
+
+void viafb_crt_enable(void)
+{
+       viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
+}
+
+void viafb_get_mmio_info(unsigned long *mmio_base,
+       unsigned long *mmio_len)
+{
+       struct pci_dev *pdev = NULL;
+       u32 vendor, device;
+       u32 i;
+
+       for (i = 0; pciidlist[i].vendor != 0; i++)
+               if (viaparinfo->chip_info->gfx_chip_name ==
+                       pciidlist[i].chip_index)
+                       break;
+
+       if (!pciidlist[i].vendor)
+               return ;
+
+       vendor = pciidlist[i].vendor;
+       device = pciidlist[i].device;
+
+       pdev = pci_get_device(vendor, device, NULL);
+
+       if (!pdev) {
+               *mmio_base = 0;
+               *mmio_len = 0;
+               return ;
+       }
+
+       *mmio_base = pci_resource_start(pdev, 1);
+       *mmio_len = pci_resource_len(pdev, 1);
+
+       pci_dev_put(pdev);
+}
+
+static void enable_second_display_channel(void)
+{
+       /* to enable second display channel. */
+       viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
+       viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
+       viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
+}
+
+static void disable_second_display_channel(void)
+{
+       /* to disable second display channel. */
+       viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
+       viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
+       viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
+}
+
+void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len)
+{
+       struct pci_dev *pdev = NULL;
+       u32 vendor, device;
+       u32 i;
+
+       for (i = 0; pciidlist[i].vendor != 0; i++)
+               if (viaparinfo->chip_info->gfx_chip_name ==
+                       pciidlist[i].chip_index)
+                       break;
+
+       if (!pciidlist[i].vendor)
+               return ;
+
+       vendor = pciidlist[i].vendor;
+       device = pciidlist[i].device;
+
+       pdev = pci_get_device(vendor, device, NULL);
+
+       if (!pdev) {
+               *fb_base = viafb_read_reg(VIASR, SR30) << 24;
+               *fb_len = viafb_get_memsize();
+               DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n");
+               DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
+               DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
+               return ;
+       }
+
+       *fb_base = (unsigned int)pci_resource_start(pdev, 0);
+       *fb_len = get_fb_size_from_pci();
+       DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n");
+       DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
+       DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
+
+       pci_dev_put(pdev);
+}
+
+static int get_fb_size_from_pci(void)
+{
+       unsigned long configid, deviceid, FBSize = 0;
+       int VideoMemSize;
+       int DeviceFound = false;
+
+       for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
+               outl(configid, (unsigned long)0xCF8);
+               deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
+
+               switch (deviceid) {
+               case CLE266:
+               case KM400:
+                       outl(configid + 0xE0, (unsigned long)0xCF8);
+                       FBSize = inl((unsigned long)0xCFC);
+                       DeviceFound = true;     /* Found device id */
+                       break;
+
+               case CN400_FUNCTION3:
+               case CN700_FUNCTION3:
+               case CX700_FUNCTION3:
+               case KM800_FUNCTION3:
+               case KM890_FUNCTION3:
+               case P4M890_FUNCTION3:
+               case P4M900_FUNCTION3:
+               case VX800_FUNCTION3:
+                       /*case CN750_FUNCTION3: */
+                       outl(configid + 0xA0, (unsigned long)0xCF8);
+                       FBSize = inl((unsigned long)0xCFC);
+                       DeviceFound = true;     /* Found device id */
+                       break;
+
+               default:
+                       break;
+               }
+
+               if (DeviceFound)
+                       break;
+       }
+
+       DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid);
+
+       FBSize = FBSize & 0x00007000;
+       DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
+
+       if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) {
+               switch (FBSize) {
+               case 0x00004000:
+                       VideoMemSize = (16 << 20);      /*16M */
+                       break;
+
+               case 0x00005000:
+                       VideoMemSize = (32 << 20);      /*32M */
+                       break;
+
+               case 0x00006000:
+                       VideoMemSize = (64 << 20);      /*64M */
+                       break;
+
+               default:
+                       VideoMemSize = (32 << 20);      /*32M */
+                       break;
+               }
+       } else {
+               switch (FBSize) {
+               case 0x00001000:
+                       VideoMemSize = (8 << 20);       /*8M */
+                       break;
+
+               case 0x00002000:
+                       VideoMemSize = (16 << 20);      /*16M */
+                       break;
+
+               case 0x00003000:
+                       VideoMemSize = (32 << 20);      /*32M */
+                       break;
+
+               case 0x00004000:
+                       VideoMemSize = (64 << 20);      /*64M */
+                       break;
+
+               case 0x00005000:
+                       VideoMemSize = (128 << 20);     /*128M */
+                       break;
+
+               case 0x00006000:
+                       VideoMemSize = (256 << 20);     /*256M */
+                       break;
+
+               default:
+                       VideoMemSize = (32 << 20);      /*32M */
+                       break;
+               }
+       }
+
+       return VideoMemSize;
+}
+
+void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
+                                       *p_gfx_dpa_setting)
+{
+       switch (output_interface) {
+       case INTERFACE_DVP0:
+               {
+                       /* DVP0 Clock Polarity and Adjust: */
+                       viafb_write_reg_mask(CR96, VIACR,
+                                      p_gfx_dpa_setting->DVP0, 0x0F);
+
+                       /* DVP0 Clock and Data Pads Driving: */
+                       viafb_write_reg_mask(SR1E, VIASR,
+                                      p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
+                       viafb_write_reg_mask(SR2A, VIASR,
+                                      p_gfx_dpa_setting->DVP0ClockDri_S1,
+                                      BIT4);
+                       viafb_write_reg_mask(SR1B, VIASR,
+                                      p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
+                       viafb_write_reg_mask(SR2A, VIASR,
+                                      p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
+                       break;
+               }
+
+       case INTERFACE_DVP1:
+               {
+                       /* DVP1 Clock Polarity and Adjust: */
+                       viafb_write_reg_mask(CR9B, VIACR,
+                                      p_gfx_dpa_setting->DVP1, 0x0F);
+
+                       /* DVP1 Clock and Data Pads Driving: */
+                       viafb_write_reg_mask(SR65, VIASR,
+                                      p_gfx_dpa_setting->DVP1Driving, 0x0F);
+                       break;
+               }
+
+       case INTERFACE_DFP_HIGH:
+               {
+                       viafb_write_reg_mask(CR97, VIACR,
+                                      p_gfx_dpa_setting->DFPHigh, 0x0F);
+                       break;
+               }
+
+       case INTERFACE_DFP_LOW:
+               {
+                       viafb_write_reg_mask(CR99, VIACR,
+                                      p_gfx_dpa_setting->DFPLow, 0x0F);
+                       break;
+               }
+
+       case INTERFACE_DFP:
+               {
+                       viafb_write_reg_mask(CR97, VIACR,
+                                      p_gfx_dpa_setting->DFPHigh, 0x0F);
+                       viafb_write_reg_mask(CR99, VIACR,
+                                      p_gfx_dpa_setting->DFPLow, 0x0F);
+                       break;
+               }
+       }
+}
+
+void viafb_memory_pitch_patch(struct fb_info *info)
+{
+       if (info->var.xres != info->var.xres_virtual) {
+               viafb_load_offset_reg(info->var.xres_virtual,
+                               info->var.bits_per_pixel >> 3, IGA1);
+
+               if (viafb_SAMM_ON) {
+                       viafb_load_offset_reg(viafb_second_virtual_xres,
+                               viafb_bpp1 >> 3,
+                                       IGA2);
+               } else {
+                       viafb_load_offset_reg(info->var.xres_virtual,
+                                       info->var.bits_per_pixel >> 3, IGA2);
+               }
+
+       }
+}
+
+/*According var's xres, yres fill var's other timing information*/
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
+                         int mode_index)
+{
+       struct VideoModeTable *vmode_tbl = NULL;
+       struct crt_mode_table *crt_timing = NULL;
+       struct display_timing crt_reg;
+       int i = 0, index = 0;
+       vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)];
+       crt_timing = vmode_tbl->crtc;
+       for (i = 0; i < vmode_tbl->mode_array; i++) {
+               index = i;
+               if (crt_timing[i].refresh_rate == refresh)
+                       break;
+       }
+
+       crt_reg = crt_timing[index].crtc;
+       switch (var->bits_per_pixel) {
+       case 8:
+               var->red.offset = 0;
+               var->green.offset = 0;
+               var->blue.offset = 0;
+               var->red.length = 6;
+               var->green.length = 6;
+               var->blue.length = 6;
+               break;
+       case 16:
+               var->red.offset = 11;
+               var->green.offset = 5;
+               var->blue.offset = 0;
+               var->red.length = 5;
+               var->green.length = 6;
+               var->blue.length = 5;
+               break;
+       case 32:
+               var->red.offset = 16;
+               var->green.offset = 8;
+               var->blue.offset = 0;
+               var->red.length = 8;
+               var->green.length = 8;
+               var->blue.length = 8;
+               break;
+       default:
+               /* never happed, put here to keep consistent */
+               break;
+       }
+
+       var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
+       var->left_margin =
+           crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
+       var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
+       var->hsync_len = crt_reg.hor_sync_end;
+       var->upper_margin =
+           crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
+       var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
+       var->vsync_len = crt_reg.ver_sync_end;
+}
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
new file mode 100644 (file)
index 0000000..6ff38fa
--- /dev/null
@@ -0,0 +1,933 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __HW_H__
+#define __HW_H__
+
+#include "global.h"
+
+/***************************************************
+* Definition IGA1 Design Method of CRTC Registers *
+****************************************************/
+#define IGA1_HOR_TOTAL_FORMULA(x)           (((x)/8)-5)
+#define IGA1_HOR_ADDR_FORMULA(x)            (((x)/8)-1)
+#define IGA1_HOR_BLANK_START_FORMULA(x)     (((x)/8)-1)
+#define IGA1_HOR_BLANK_END_FORMULA(x, y)     (((x+y)/8)-1)
+#define IGA1_HOR_SYNC_START_FORMULA(x)      ((x)/8)
+#define IGA1_HOR_SYNC_END_FORMULA(x, y)      ((x+y)/8)
+
+#define IGA1_VER_TOTAL_FORMULA(x)           ((x)-2)
+#define IGA1_VER_ADDR_FORMULA(x)            ((x)-1)
+#define IGA1_VER_BLANK_START_FORMULA(x)     ((x)-1)
+#define IGA1_VER_BLANK_END_FORMULA(x, y)     ((x+y)-1)
+#define IGA1_VER_SYNC_START_FORMULA(x)      ((x)-1)
+#define IGA1_VER_SYNC_END_FORMULA(x, y)      ((x+y)-1)
+
+/***************************************************
+** Definition IGA2 Design Method of CRTC Registers *
+****************************************************/
+#define IGA2_HOR_TOTAL_FORMULA(x)           ((x)-1)
+#define IGA2_HOR_ADDR_FORMULA(x)            ((x)-1)
+#define IGA2_HOR_BLANK_START_FORMULA(x)     ((x)-1)
+#define IGA2_HOR_BLANK_END_FORMULA(x, y)     ((x+y)-1)
+#define IGA2_HOR_SYNC_START_FORMULA(x)      ((x)-1)
+#define IGA2_HOR_SYNC_END_FORMULA(x, y)      ((x+y)-1)
+
+#define IGA2_VER_TOTAL_FORMULA(x)           ((x)-1)
+#define IGA2_VER_ADDR_FORMULA(x)            ((x)-1)
+#define IGA2_VER_BLANK_START_FORMULA(x)     ((x)-1)
+#define IGA2_VER_BLANK_END_FORMULA(x, y)     ((x+y)-1)
+#define IGA2_VER_SYNC_START_FORMULA(x)      ((x)-1)
+#define IGA2_VER_SYNC_END_FORMULA(x, y)      ((x+y)-1)
+
+/**********************************************************/
+/* Definition IGA2 Design Method of CRTC Shadow Registers */
+/**********************************************************/
+#define IGA2_HOR_TOTAL_SHADOW_FORMULA(x)           ((x/8)-5)
+#define IGA2_HOR_BLANK_END_SHADOW_FORMULA(x, y)     (((x+y)/8)-1)
+#define IGA2_VER_TOTAL_SHADOW_FORMULA(x)           ((x)-2)
+#define IGA2_VER_ADDR_SHADOW_FORMULA(x)            ((x)-1)
+#define IGA2_VER_BLANK_START_SHADOW_FORMULA(x)     ((x)-1)
+#define IGA2_VER_BLANK_END_SHADOW_FORMULA(x, y)     ((x+y)-1)
+#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x)      (x)
+#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y)      (x+y)
+
+/* Define Register Number for IGA1 CRTC Timing */
+
+/* location: {CR00,0,7},{CR36,3,3} */
+#define IGA1_HOR_TOTAL_REG_NUM         2
+/* location: {CR01,0,7} */
+#define IGA1_HOR_ADDR_REG_NUM          1
+/* location: {CR02,0,7} */
+#define IGA1_HOR_BLANK_START_REG_NUM    1
+/* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */
+#define IGA1_HOR_BLANK_END_REG_NUM     3
+/* location: {CR04,0,7},{CR33,4,4} */
+#define IGA1_HOR_SYNC_START_REG_NUM    2
+/* location: {CR05,0,4} */
+#define IGA1_HOR_SYNC_END_REG_NUM       1
+/* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */
+#define IGA1_VER_TOTAL_REG_NUM          4
+/* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */
+#define IGA1_VER_ADDR_REG_NUM           4
+/* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */
+#define IGA1_VER_BLANK_START_REG_NUM    4
+/* location: {CR16,0,7} */
+#define IGA1_VER_BLANK_END_REG_NUM      1
+/* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */
+#define IGA1_VER_SYNC_START_REG_NUM     4
+/* location: {CR11,0,3} */
+#define IGA1_VER_SYNC_END_REG_NUM       1
+
+/* Define Register Number for IGA2 Shadow CRTC Timing */
+
+/* location: {CR6D,0,7},{CR71,3,3} */
+#define IGA2_SHADOW_HOR_TOTAL_REG_NUM       2
+/* location: {CR6E,0,7} */
+#define IGA2_SHADOW_HOR_BLANK_END_REG_NUM   1
+/* location: {CR6F,0,7},{CR71,0,2} */
+#define IGA2_SHADOW_VER_TOTAL_REG_NUM       2
+/* location: {CR70,0,7},{CR71,4,6} */
+#define IGA2_SHADOW_VER_ADDR_REG_NUM        2
+/* location: {CR72,0,7},{CR74,4,6} */
+#define IGA2_SHADOW_VER_BLANK_START_REG_NUM 2
+/* location: {CR73,0,7},{CR74,0,2} */
+#define IGA2_SHADOW_VER_BLANK_END_REG_NUM   2
+/* location: {CR75,0,7},{CR76,4,6} */
+#define IGA2_SHADOW_VER_SYNC_START_REG_NUM  2
+/* location: {CR76,0,3} */
+#define IGA2_SHADOW_VER_SYNC_END_REG_NUM    1
+
+/* Define Register Number for IGA2 CRTC Timing */
+
+/* location: {CR50,0,7},{CR55,0,3} */
+#define IGA2_HOR_TOTAL_REG_NUM          2
+/* location: {CR51,0,7},{CR55,4,6} */
+#define IGA2_HOR_ADDR_REG_NUM           2
+/* location: {CR52,0,7},{CR54,0,2} */
+#define IGA2_HOR_BLANK_START_REG_NUM    2
+/* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6]
+is reserved, so it may have problem to set 1600x1200 on IGA2. */
+/*             Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */
+#define IGA2_HOR_BLANK_END_REG_NUM      3
+/* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */
+/* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */
+#define IGA2_HOR_SYNC_START_REG_NUM     4
+
+/* location: {CR57,0,7},{CR5C,6,6} */
+#define IGA2_HOR_SYNC_END_REG_NUM       2
+/* location: {CR58,0,7},{CR5D,0,2} */
+#define IGA2_VER_TOTAL_REG_NUM          2
+/* location: {CR59,0,7},{CR5D,3,5} */
+#define IGA2_VER_ADDR_REG_NUM           2
+/* location: {CR5A,0,7},{CR5C,0,2} */
+#define IGA2_VER_BLANK_START_REG_NUM    2
+/* location: {CR5E,0,7},{CR5C,3,5} */
+#define IGA2_VER_BLANK_END_REG_NUM      2
+/* location: {CR5E,0,7},{CR5F,5,7} */
+#define IGA2_VER_SYNC_START_REG_NUM     2
+/* location: {CR5F,0,4} */
+#define IGA2_VER_SYNC_END_REG_NUM       1
+
+/* Define Offset and Fetch Count Register*/
+
+/* location: {CR13,0,7},{CR35,5,7} */
+#define IGA1_OFFSET_REG_NUM             2
+/* 8 bytes alignment. */
+#define IGA1_OFFSER_ALIGN_BYTE          8
+/* x: H resolution, y: color depth */
+#define IGA1_OFFSET_FORMULA(x, y)        ((x*y)/IGA1_OFFSER_ALIGN_BYTE)
+/* location: {SR1C,0,7},{SR1D,0,1} */
+#define IGA1_FETCH_COUNT_REG_NUM        2
+/* 16 bytes alignment. */
+#define IGA1_FETCH_COUNT_ALIGN_BYTE     16
+/* x: H resolution, y: color depth */
+#define IGA1_FETCH_COUNT_PATCH_VALUE    4
+#define IGA1_FETCH_COUNT_FORMULA(x, y)   \
+       (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE)
+
+/* location: {CR66,0,7},{CR67,0,1} */
+#define IGA2_OFFSET_REG_NUM             2
+#define IGA2_OFFSET_ALIGN_BYTE          8
+/* x: H resolution, y: color depth */
+#define IGA2_OFFSET_FORMULA(x, y)        ((x*y)/IGA2_OFFSET_ALIGN_BYTE)
+/* location: {CR65,0,7},{CR67,2,3} */
+#define IGA2_FETCH_COUNT_REG_NUM        2
+#define IGA2_FETCH_COUNT_ALIGN_BYTE     16
+#define IGA2_FETCH_COUNT_PATCH_VALUE    0
+#define IGA2_FETCH_COUNT_FORMULA(x, y)   \
+       (((x*y)/IGA2_FETCH_COUNT_ALIGN_BYTE) + IGA2_FETCH_COUNT_PATCH_VALUE)
+
+/* Staring Address*/
+
+/* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */
+#define IGA1_STARTING_ADDR_REG_NUM      4
+/* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */
+#define IGA2_STARTING_ADDR_REG_NUM      3
+
+/* Define Display OFFSET*/
+/* These value are by HW suggested value*/
+/* location: {SR17,0,7} */
+#define K800_IGA1_FIFO_MAX_DEPTH                384
+/* location: {SR16,0,5},{SR16,7,7} */
+#define K800_IGA1_FIFO_THRESHOLD                328
+/* location: {SR18,0,5},{SR18,7,7} */
+#define K800_IGA1_FIFO_HIGH_THRESHOLD           296
+/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
+                               /* because HW only 5 bits */
+#define K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM      0
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define K800_IGA2_FIFO_MAX_DEPTH                384
+/* location: {CR68,0,3},{CR95,4,6} */
+#define K800_IGA2_FIFO_THRESHOLD                328
+/* location: {CR92,0,3},{CR95,0,2} */
+#define K800_IGA2_FIFO_HIGH_THRESHOLD           296
+/* location: {CR94,0,6} */
+#define K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM      128
+
+/* location: {SR17,0,7} */
+#define P880_IGA1_FIFO_MAX_DEPTH                192
+/* location: {SR16,0,5},{SR16,7,7} */
+#define P880_IGA1_FIFO_THRESHOLD                128
+/* location: {SR18,0,5},{SR18,7,7} */
+#define P880_IGA1_FIFO_HIGH_THRESHOLD           64
+/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
+                               /* because HW only 5 bits */
+#define P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM      0
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define P880_IGA2_FIFO_MAX_DEPTH                96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define P880_IGA2_FIFO_THRESHOLD                64
+/* location: {CR92,0,3},{CR95,0,2} */
+#define P880_IGA2_FIFO_HIGH_THRESHOLD           32
+/* location: {CR94,0,6} */
+#define P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM      128
+
+/* VT3314 chipset*/
+
+/* location: {SR17,0,7} */
+#define CN700_IGA1_FIFO_MAX_DEPTH               96
+/* location: {SR16,0,5},{SR16,7,7} */
+#define CN700_IGA1_FIFO_THRESHOLD               80
+/* location: {SR18,0,5},{SR18,7,7} */
+#define CN700_IGA1_FIFO_HIGH_THRESHOLD          64
+/* location: {SR22,0,4}. (128/4) =64, P800 must be set zero,
+                               because HW only 5 bits */
+#define CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM     0
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define CN700_IGA2_FIFO_MAX_DEPTH               96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define CN700_IGA2_FIFO_THRESHOLD               80
+/* location: {CR92,0,3},{CR95,0,2} */
+#define CN700_IGA2_FIFO_HIGH_THRESHOLD          32
+/* location: {CR94,0,6} */
+#define CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM     128
+
+/* For VT3324, these values are suggested by HW */
+/* location: {SR17,0,7} */
+#define CX700_IGA1_FIFO_MAX_DEPTH               192
+/* location: {SR16,0,5},{SR16,7,7} */
+#define CX700_IGA1_FIFO_THRESHOLD               128
+/* location: {SR18,0,5},{SR18,7,7} */
+#define CX700_IGA1_FIFO_HIGH_THRESHOLD          128
+/* location: {SR22,0,4} */
+#define CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM     124
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define CX700_IGA2_FIFO_MAX_DEPTH               96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define CX700_IGA2_FIFO_THRESHOLD               64
+/* location: {CR92,0,3},{CR95,0,2} */
+#define CX700_IGA2_FIFO_HIGH_THRESHOLD          32
+/* location: {CR94,0,6} */
+#define CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM     128
+
+/* VT3336 chipset*/
+/* location: {SR17,0,7} */
+#define K8M890_IGA1_FIFO_MAX_DEPTH               360
+/* location: {SR16,0,5},{SR16,7,7} */
+#define K8M890_IGA1_FIFO_THRESHOLD               328
+/* location: {SR18,0,5},{SR18,7,7} */
+#define K8M890_IGA1_FIFO_HIGH_THRESHOLD          296
+/* location: {SR22,0,4}. */
+#define K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM     124
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define K8M890_IGA2_FIFO_MAX_DEPTH               360
+/* location: {CR68,0,3},{CR95,4,6} */
+#define K8M890_IGA2_FIFO_THRESHOLD               328
+/* location: {CR92,0,3},{CR95,0,2} */
+#define K8M890_IGA2_FIFO_HIGH_THRESHOLD          296
+/* location: {CR94,0,6} */
+#define K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM     124
+
+/* VT3327 chipset*/
+/* location: {SR17,0,7} */
+#define P4M890_IGA1_FIFO_MAX_DEPTH               96
+/* location: {SR16,0,5},{SR16,7,7} */
+#define P4M890_IGA1_FIFO_THRESHOLD               76
+/* location: {SR18,0,5},{SR18,7,7} */
+#define P4M890_IGA1_FIFO_HIGH_THRESHOLD          64
+/* location: {SR22,0,4}. (32/4) =8 */
+#define P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM     32
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define P4M890_IGA2_FIFO_MAX_DEPTH               96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define P4M890_IGA2_FIFO_THRESHOLD               76
+/* location: {CR92,0,3},{CR95,0,2} */
+#define P4M890_IGA2_FIFO_HIGH_THRESHOLD          64
+/* location: {CR94,0,6} */
+#define P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM     32
+
+/* VT3364 chipset*/
+/* location: {SR17,0,7} */
+#define P4M900_IGA1_FIFO_MAX_DEPTH               96
+/* location: {SR16,0,5},{SR16,7,7} */
+#define P4M900_IGA1_FIFO_THRESHOLD               76
+/* location: {SR18,0,5},{SR18,7,7} */
+#define P4M900_IGA1_FIFO_HIGH_THRESHOLD          76
+/* location: {SR22,0,4}. */
+#define P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM     32
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define P4M900_IGA2_FIFO_MAX_DEPTH               96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define P4M900_IGA2_FIFO_THRESHOLD               76
+/* location: {CR92,0,3},{CR95,0,2} */
+#define P4M900_IGA2_FIFO_HIGH_THRESHOLD          76
+/* location: {CR94,0,6} */
+#define P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM     32
+
+/* For VT3353, these values are suggested by HW */
+/* location: {SR17,0,7} */
+#define VX800_IGA1_FIFO_MAX_DEPTH               192
+/* location: {SR16,0,5},{SR16,7,7} */
+#define VX800_IGA1_FIFO_THRESHOLD               152
+/* location: {SR18,0,5},{SR18,7,7} */
+#define VX800_IGA1_FIFO_HIGH_THRESHOLD          152
+/* location: {SR22,0,4} */
+#define VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM      64
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define VX800_IGA2_FIFO_MAX_DEPTH               96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define VX800_IGA2_FIFO_THRESHOLD               64
+/* location: {CR92,0,3},{CR95,0,2} */
+#define VX800_IGA2_FIFO_HIGH_THRESHOLD          32
+/* location: {CR94,0,6} */
+#define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM     128
+
+#define IGA1_FIFO_DEPTH_SELECT_REG_NUM          1
+#define IGA1_FIFO_THRESHOLD_REG_NUM             2
+#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM        2
+#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM   1
+
+#define IGA2_FIFO_DEPTH_SELECT_REG_NUM          3
+#define IGA2_FIFO_THRESHOLD_REG_NUM             2
+#define IGA2_FIFO_HIGH_THRESHOLD_REG_NUM        2
+#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM   1
+
+#define IGA1_FIFO_DEPTH_SELECT_FORMULA(x)                   ((x/2)-1)
+#define IGA1_FIFO_THRESHOLD_FORMULA(x)                      (x/4)
+#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x)            (x/4)
+#define IGA1_FIFO_HIGH_THRESHOLD_FORMULA(x)                 (x/4)
+#define IGA2_FIFO_DEPTH_SELECT_FORMULA(x)                   (((x/2)/4)-1)
+#define IGA2_FIFO_THRESHOLD_FORMULA(x)                      (x/4)
+#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x)            (x/4)
+#define IGA2_FIFO_HIGH_THRESHOLD_FORMULA(x)                 (x/4)
+
+/************************************************************************/
+/*  LCD Timing                                                          */
+/************************************************************************/
+
+/* 500 ms = 500000 us */
+#define LCD_POWER_SEQ_TD0               500000
+/* 50 ms = 50000 us */
+#define LCD_POWER_SEQ_TD1               50000
+/* 0 us */
+#define LCD_POWER_SEQ_TD2               0
+/* 210 ms = 210000 us */
+#define LCD_POWER_SEQ_TD3               210000
+/* 2^10 * (1/14.31818M) = 71.475 us (K400.revA) */
+#define CLE266_POWER_SEQ_UNIT           71
+/* 2^11 * (1/14.31818M) = 142.95 us (K400.revB) */
+#define K800_POWER_SEQ_UNIT             142
+/* 2^13 * (1/14.31818M) = 572.1 us */
+#define P880_POWER_SEQ_UNIT             572
+
+#define CLE266_POWER_SEQ_FORMULA(x)     ((x)/CLE266_POWER_SEQ_UNIT)
+#define K800_POWER_SEQ_FORMULA(x)       ((x)/K800_POWER_SEQ_UNIT)
+#define P880_POWER_SEQ_FORMULA(x)       ((x)/P880_POWER_SEQ_UNIT)
+
+/* location: {CR8B,0,7},{CR8F,0,3} */
+#define LCD_POWER_SEQ_TD0_REG_NUM       2
+/* location: {CR8C,0,7},{CR8F,4,7} */
+#define LCD_POWER_SEQ_TD1_REG_NUM       2
+/* location: {CR8D,0,7},{CR90,0,3} */
+#define LCD_POWER_SEQ_TD2_REG_NUM       2
+/* location: {CR8E,0,7},{CR90,4,7} */
+#define LCD_POWER_SEQ_TD3_REG_NUM       2
+
+/* LCD Scaling factor*/
+/* x: indicate setting horizontal size*/
+/* y: indicate panel horizontal size*/
+
+/* Horizontal scaling factor 10 bits (2^10) */
+#define CLE266_LCD_HOR_SCF_FORMULA(x, y)   (((x-1)*1024)/(y-1))
+/* Vertical scaling factor 10 bits (2^10) */
+#define CLE266_LCD_VER_SCF_FORMULA(x, y)   (((x-1)*1024)/(y-1))
+/* Horizontal scaling factor 10 bits (2^12) */
+#define K800_LCD_HOR_SCF_FORMULA(x, y)     (((x-1)*4096)/(y-1))
+/* Vertical scaling factor 10 bits (2^11) */
+#define K800_LCD_VER_SCF_FORMULA(x, y)     (((x-1)*2048)/(y-1))
+
+/* location: {CR9F,0,1},{CR77,0,7},{CR79,4,5} */
+#define LCD_HOR_SCALING_FACTOR_REG_NUM  3
+/* location: {CR79,3,3},{CR78,0,7},{CR79,6,7} */
+#define LCD_VER_SCALING_FACTOR_REG_NUM  3
+/* location: {CR77,0,7},{CR79,4,5} */
+#define LCD_HOR_SCALING_FACTOR_REG_NUM_CLE  2
+/* location: {CR78,0,7},{CR79,6,7} */
+#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE  2
+
+/************************************************
+ *****     Define IGA1 Display Timing       *****
+ ************************************************/
+struct io_register {
+       u8 io_addr;
+       u8 start_bit;
+       u8 end_bit;
+};
+
+/* IGA1 Horizontal Total */
+struct iga1_hor_total {
+       int reg_num;
+       struct io_register reg[IGA1_HOR_TOTAL_REG_NUM];
+};
+
+/* IGA1 Horizontal Addressable Video */
+struct iga1_hor_addr {
+       int reg_num;
+       struct io_register reg[IGA1_HOR_ADDR_REG_NUM];
+};
+
+/* IGA1 Horizontal Blank Start */
+struct iga1_hor_blank_start {
+       int reg_num;
+       struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM];
+};
+
+/* IGA1 Horizontal Blank End */
+struct iga1_hor_blank_end {
+       int reg_num;
+       struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM];
+};
+
+/* IGA1 Horizontal Sync Start */
+struct iga1_hor_sync_start {
+       int reg_num;
+       struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM];
+};
+
+/* IGA1 Horizontal Sync End */
+struct iga1_hor_sync_end {
+       int reg_num;
+       struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM];
+};
+
+/* IGA1 Vertical Total */
+struct iga1_ver_total {
+       int reg_num;
+       struct io_register reg[IGA1_VER_TOTAL_REG_NUM];
+};
+
+/* IGA1 Vertical Addressable Video */
+struct iga1_ver_addr {
+       int reg_num;
+       struct io_register reg[IGA1_VER_ADDR_REG_NUM];
+};
+
+/* IGA1 Vertical Blank Start */
+struct iga1_ver_blank_start {
+       int reg_num;
+       struct io_register reg[IGA1_VER_BLANK_START_REG_NUM];
+};
+
+/* IGA1 Vertical Blank End */
+struct iga1_ver_blank_end {
+       int reg_num;
+       struct io_register reg[IGA1_VER_BLANK_END_REG_NUM];
+};
+
+/* IGA1 Vertical Sync Start */
+struct iga1_ver_sync_start {
+       int reg_num;
+       struct io_register reg[IGA1_VER_SYNC_START_REG_NUM];
+};
+
+/* IGA1 Vertical Sync End */
+struct iga1_ver_sync_end {
+       int reg_num;
+       struct io_register reg[IGA1_VER_SYNC_END_REG_NUM];
+};
+
+/*****************************************************
+**      Define IGA2 Shadow Display Timing         ****
+*****************************************************/
+
+/* IGA2 Shadow Horizontal Total */
+struct iga2_shadow_hor_total {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_HOR_TOTAL_REG_NUM];
+};
+
+/* IGA2 Shadow Horizontal Blank End */
+struct iga2_shadow_hor_blank_end {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_HOR_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Total */
+struct iga2_shadow_ver_total {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_VER_TOTAL_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Addressable Video */
+struct iga2_shadow_ver_addr {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_VER_ADDR_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Blank Start */
+struct iga2_shadow_ver_blank_start {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_VER_BLANK_START_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Blank End */
+struct iga2_shadow_ver_blank_end {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_VER_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Sync Start */
+struct iga2_shadow_ver_sync_start {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_VER_SYNC_START_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Sync End */
+struct iga2_shadow_ver_sync_end {
+       int reg_num;
+       struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM];
+};
+
+/*****************************************************
+**      Define IGA2 Display Timing                ****
+******************************************************/
+
+/* IGA2 Horizontal Total */
+struct iga2_hor_total {
+       int reg_num;
+       struct io_register reg[IGA2_HOR_TOTAL_REG_NUM];
+};
+
+/* IGA2 Horizontal Addressable Video */
+struct iga2_hor_addr {
+       int reg_num;
+       struct io_register reg[IGA2_HOR_ADDR_REG_NUM];
+};
+
+/* IGA2 Horizontal Blank Start */
+struct iga2_hor_blank_start {
+       int reg_num;
+       struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM];
+};
+
+/* IGA2 Horizontal Blank End */
+struct iga2_hor_blank_end {
+       int reg_num;
+       struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Horizontal Sync Start */
+struct iga2_hor_sync_start {
+       int reg_num;
+       struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM];
+};
+
+/* IGA2 Horizontal Sync End */
+struct iga2_hor_sync_end {
+       int reg_num;
+       struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM];
+};
+
+/* IGA2 Vertical Total */
+struct iga2_ver_total {
+       int reg_num;
+       struct io_register reg[IGA2_VER_TOTAL_REG_NUM];
+};
+
+/* IGA2 Vertical Addressable Video */
+struct iga2_ver_addr {
+       int reg_num;
+       struct io_register reg[IGA2_VER_ADDR_REG_NUM];
+};
+
+/* IGA2 Vertical Blank Start */
+struct iga2_ver_blank_start {
+       int reg_num;
+       struct io_register reg[IGA2_VER_BLANK_START_REG_NUM];
+};
+
+/* IGA2 Vertical Blank End */
+struct iga2_ver_blank_end {
+       int reg_num;
+       struct io_register reg[IGA2_VER_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Vertical Sync Start */
+struct iga2_ver_sync_start {
+       int reg_num;
+       struct io_register reg[IGA2_VER_SYNC_START_REG_NUM];
+};
+
+/* IGA2 Vertical Sync End */
+struct iga2_ver_sync_end {
+       int reg_num;
+       struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
+};
+
+/* IGA1 Offset Register */
+struct iga1_offset {
+       int reg_num;
+       struct io_register reg[IGA1_OFFSET_REG_NUM];
+};
+
+/* IGA2 Offset Register */
+struct iga2_offset {
+       int reg_num;
+       struct io_register reg[IGA2_OFFSET_REG_NUM];
+};
+
+struct offset {
+       struct iga1_offset iga1_offset_reg;
+       struct iga2_offset iga2_offset_reg;
+};
+
+/* IGA1 Fetch Count Register */
+struct iga1_fetch_count {
+       int reg_num;
+       struct io_register reg[IGA1_FETCH_COUNT_REG_NUM];
+};
+
+/* IGA2 Fetch Count Register */
+struct iga2_fetch_count {
+       int reg_num;
+       struct io_register reg[IGA2_FETCH_COUNT_REG_NUM];
+};
+
+struct fetch_count {
+       struct iga1_fetch_count iga1_fetch_count_reg;
+       struct iga2_fetch_count iga2_fetch_count_reg;
+};
+
+/* Starting Address Register */
+struct iga1_starting_addr {
+       int reg_num;
+       struct io_register reg[IGA1_STARTING_ADDR_REG_NUM];
+};
+
+struct iga2_starting_addr {
+       int reg_num;
+       struct io_register reg[IGA2_STARTING_ADDR_REG_NUM];
+};
+
+struct starting_addr {
+       struct iga1_starting_addr iga1_starting_addr_reg;
+       struct iga2_starting_addr iga2_starting_addr_reg;
+};
+
+/* LCD Power Sequence Timer */
+struct lcd_pwd_seq_td0 {
+       int reg_num;
+       struct io_register reg[LCD_POWER_SEQ_TD0_REG_NUM];
+};
+
+struct lcd_pwd_seq_td1 {
+       int reg_num;
+       struct io_register reg[LCD_POWER_SEQ_TD1_REG_NUM];
+};
+
+struct lcd_pwd_seq_td2 {
+       int reg_num;
+       struct io_register reg[LCD_POWER_SEQ_TD2_REG_NUM];
+};
+
+struct lcd_pwd_seq_td3 {
+       int reg_num;
+       struct io_register reg[LCD_POWER_SEQ_TD3_REG_NUM];
+};
+
+struct _lcd_pwd_seq_timer {
+       struct lcd_pwd_seq_td0 td0;
+       struct lcd_pwd_seq_td1 td1;
+       struct lcd_pwd_seq_td2 td2;
+       struct lcd_pwd_seq_td3 td3;
+};
+
+/* LCD Scaling Factor */
+struct _lcd_hor_scaling_factor {
+       int reg_num;
+       struct io_register reg[LCD_HOR_SCALING_FACTOR_REG_NUM];
+};
+
+struct _lcd_ver_scaling_factor {
+       int reg_num;
+       struct io_register reg[LCD_VER_SCALING_FACTOR_REG_NUM];
+};
+
+struct _lcd_scaling_factor {
+       struct _lcd_hor_scaling_factor lcd_hor_scaling_factor;
+       struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
+};
+
+struct pll_map {
+       u32 clk;
+       u32 cle266_pll;
+       u32 k800_pll;
+       u32 cx700_pll;
+};
+
+struct rgbLUT {
+       u8 red;
+       u8 green;
+       u8 blue;
+};
+
+struct lcd_pwd_seq_timer {
+       u16 td0;
+       u16 td1;
+       u16 td2;
+       u16 td3;
+};
+
+/* Display FIFO Relation Registers*/
+struct iga1_fifo_depth_select {
+       int reg_num;
+       struct io_register reg[IGA1_FIFO_DEPTH_SELECT_REG_NUM];
+};
+
+struct iga1_fifo_threshold_select {
+       int reg_num;
+       struct io_register reg[IGA1_FIFO_THRESHOLD_REG_NUM];
+};
+
+struct iga1_fifo_high_threshold_select {
+       int reg_num;
+       struct io_register reg[IGA1_FIFO_HIGH_THRESHOLD_REG_NUM];
+};
+
+struct iga1_display_queue_expire_num {
+       int reg_num;
+       struct io_register reg[IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
+};
+
+struct iga2_fifo_depth_select {
+       int reg_num;
+       struct io_register reg[IGA2_FIFO_DEPTH_SELECT_REG_NUM];
+};
+
+struct iga2_fifo_threshold_select {
+       int reg_num;
+       struct io_register reg[IGA2_FIFO_THRESHOLD_REG_NUM];
+};
+
+struct iga2_fifo_high_threshold_select {
+       int reg_num;
+       struct io_register reg[IGA2_FIFO_HIGH_THRESHOLD_REG_NUM];
+};
+
+struct iga2_display_queue_expire_num {
+       int reg_num;
+       struct io_register reg[IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
+};
+
+struct fifo_depth_select {
+       struct iga1_fifo_depth_select iga1_fifo_depth_select_reg;
+       struct iga2_fifo_depth_select iga2_fifo_depth_select_reg;
+};
+
+struct fifo_threshold_select {
+       struct iga1_fifo_threshold_select iga1_fifo_threshold_select_reg;
+       struct iga2_fifo_threshold_select iga2_fifo_threshold_select_reg;
+};
+
+struct fifo_high_threshold_select {
+       struct iga1_fifo_high_threshold_select
+        iga1_fifo_high_threshold_select_reg;
+       struct iga2_fifo_high_threshold_select
+        iga2_fifo_high_threshold_select_reg;
+};
+
+struct display_queue_expire_num {
+       struct iga1_display_queue_expire_num
+        iga1_display_queue_expire_num_reg;
+       struct iga2_display_queue_expire_num
+        iga2_display_queue_expire_num_reg;
+};
+
+struct iga1_crtc_timing {
+       struct iga1_hor_total hor_total;
+       struct iga1_hor_addr hor_addr;
+       struct iga1_hor_blank_start hor_blank_start;
+       struct iga1_hor_blank_end hor_blank_end;
+       struct iga1_hor_sync_start hor_sync_start;
+       struct iga1_hor_sync_end hor_sync_end;
+       struct iga1_ver_total ver_total;
+       struct iga1_ver_addr ver_addr;
+       struct iga1_ver_blank_start ver_blank_start;
+       struct iga1_ver_blank_end ver_blank_end;
+       struct iga1_ver_sync_start ver_sync_start;
+       struct iga1_ver_sync_end ver_sync_end;
+};
+
+struct iga2_shadow_crtc_timing {
+       struct iga2_shadow_hor_total hor_total_shadow;
+       struct iga2_shadow_hor_blank_end hor_blank_end_shadow;
+       struct iga2_shadow_ver_total ver_total_shadow;
+       struct iga2_shadow_ver_addr ver_addr_shadow;
+       struct iga2_shadow_ver_blank_start ver_blank_start_shadow;
+       struct iga2_shadow_ver_blank_end ver_blank_end_shadow;
+       struct iga2_shadow_ver_sync_start ver_sync_start_shadow;
+       struct iga2_shadow_ver_sync_end ver_sync_end_shadow;
+};
+
+struct iga2_crtc_timing {
+       struct iga2_hor_total hor_total;
+       struct iga2_hor_addr hor_addr;
+       struct iga2_hor_blank_start hor_blank_start;
+       struct iga2_hor_blank_end hor_blank_end;
+       struct iga2_hor_sync_start hor_sync_start;
+       struct iga2_hor_sync_end hor_sync_end;
+       struct iga2_ver_total ver_total;
+       struct iga2_ver_addr ver_addr;
+       struct iga2_ver_blank_start ver_blank_start;
+       struct iga2_ver_blank_end ver_blank_end;
+       struct iga2_ver_sync_start ver_sync_start;
+       struct iga2_ver_sync_end ver_sync_end;
+};
+
+/* device ID */
+#define CLE266              0x3123
+#define KM400               0x3205
+#define CN400_FUNCTION2     0x2259
+#define CN400_FUNCTION3     0x3259
+/* support VT3314 chipset */
+#define CN700_FUNCTION2     0x2314
+#define CN700_FUNCTION3     0x3208
+/* VT3324 chipset */
+#define CX700_FUNCTION2     0x2324
+#define CX700_FUNCTION3     0x3324
+/* VT3204 chipset*/
+#define KM800_FUNCTION3      0x3204
+/* VT3336 chipset*/
+#define KM890_FUNCTION3      0x3336
+/* VT3327 chipset*/
+#define P4M890_FUNCTION3     0x3327
+/* VT3293 chipset*/
+#define CN750_FUNCTION3     0x3208
+/* VT3364 chipset*/
+#define P4M900_FUNCTION3    0x3364
+/* VT3353 chipset*/
+#define VX800_FUNCTION3     0x3353
+
+#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
+
+struct IODATA {
+       u8 Index;
+       u8 Mask;
+       u8 Data;
+};
+
+struct pci_device_id_info {
+       u32 vendor;
+       u32 device;
+       u32 chip_index;
+};
+
+extern unsigned int viafb_second_virtual_xres;
+extern unsigned int viafb_second_offset;
+extern int viafb_second_size;
+extern int viafb_SAMM_ON;
+extern int viafb_dual_fb;
+extern int viafb_LCD2_ON;
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+extern int viafb_accel;
+extern int viafb_hotplug;
+
+void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
+void viafb_set_output_path(int device, int set_iga,
+       int output_interface);
+void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
+                     int mode_index, int bpp_byte, int set_iga);
+
+void viafb_set_vclock(u32 CLK, int set_iga);
+void viafb_load_reg(int timing_value, int viafb_load_reg_num,
+       struct io_register *reg,
+             int io_type);
+void viafb_crt_disable(void);
+void viafb_crt_enable(void);
+void init_ad9389(void);
+/* Access I/O Function */
+void viafb_write_reg(u8 index, u16 io_port, u8 data);
+u8 viafb_read_reg(int io_port, u8 index);
+void viafb_lock_crt(void);
+void viafb_unlock_crt(void);
+void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga);
+void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
+void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
+struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
+u32 viafb_get_clk_value(int clk);
+void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
+void viafb_set_color_depth(int bpp_byte, int set_iga);
+void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
+                                       *p_gfx_dpa_setting);
+
+int viafb_setmode(int vmode_index, int hor_res, int ver_res,
+           int video_bpp, int vmode_index1, int hor_res1,
+           int ver_res1, int video_bpp1);
+void viafb_init_chip_info(void);
+void viafb_init_dac(int set_iga);
+int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
+int viafb_get_refresh(int hres, int vres, u32 float_refresh);
+void viafb_update_device_setting(int hres, int vres, int bpp,
+                          int vmode_refresh, int flag);
+void viafb_get_mmio_info(unsigned long *mmio_base,
+       unsigned long *mmio_len);
+
+void viafb_set_iga_path(void);
+void viafb_set_start_addr(void);
+void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
+
+#endif /* __HW_H__ */
diff --git a/drivers/video/via/iface.c b/drivers/video/via/iface.c
new file mode 100644 (file)
index 0000000..1570636
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+/* Get frame buffer size from VGA BIOS */
+
+unsigned int viafb_get_memsize(void)
+{
+       unsigned int m;
+
+       /* If memory size provided by user */
+       if (viafb_memsize)
+               m = viafb_memsize * Mb;
+       else {
+               m = (unsigned int)viafb_read_reg(VIASR, SR39);
+               m = m * (4 * Mb);
+
+               if ((m < (16 * Mb)) || (m > (64 * Mb)))
+                       m = 16 * Mb;
+       }
+       DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb);
+       return m;
+}
+
+/* Get Video Buffer Starting Physical Address(back door)*/
+
+unsigned long viafb_get_videobuf_addr(void)
+{
+       struct pci_dev *pdev = NULL;
+       unsigned char sys_mem;
+       unsigned char video_mem;
+       unsigned long sys_mem_size;
+       unsigned long video_mem_size;
+       /*system memory = 256 MB, video memory 64 MB */
+       unsigned long vmem_starting_adr = 0x0C000000;
+
+       pdev =
+           (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID,
+                                            VIA_K800_BRIDGE_DID, NULL);
+       if (pdev != NULL) {
+               pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG,
+                                    &sys_mem);
+               pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG,
+                                    &video_mem);
+               video_mem = (video_mem & 0x70) >> 4;
+               sys_mem_size = ((unsigned long)sys_mem) << 24;
+               if (video_mem != 0)
+                       video_mem_size = (1 << (video_mem)) * 1024 * 1024;
+               else
+                       video_mem_size = 0;
+
+               vmem_starting_adr = sys_mem_size - video_mem_size;
+               pci_dev_put(pdev);
+       }
+
+       DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n",
+                 vmem_starting_adr);
+       return vmem_starting_adr;
+}
diff --git a/drivers/video/via/iface.h b/drivers/video/via/iface.h
new file mode 100644 (file)
index 0000000..790ec3e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IFACE_H__
+#define __IFACE_H__
+
+#define Kb  (1024)
+#define Mb  (Kb*Kb)
+
+#define VIA_K800_BRIDGE_VID         0x1106
+#define VIA_K800_BRIDGE_DID         0x3204
+
+#define VIA_K800_SYSTEM_MEMORY_REG  0x47
+#define VIA_K800_VIDEO_MEMORY_REG   0xA1
+
+extern int viafb_memsize;
+unsigned int viafb_get_memsize(void);
+unsigned long viafb_get_videobuf_addr(void);
+
+#endif /* __IFACE_H__ */
diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c
new file mode 100644 (file)
index 0000000..da03c07
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+int viafb_ioctl_get_viafb_info(u_long arg)
+{
+       struct viafb_ioctl_info viainfo;
+
+       viainfo.viafb_id = VIAID;
+       viainfo.vendor_id = PCI_VIA_VENDOR_ID;
+
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_CLE266:
+               viainfo.device_id = UNICHROME_CLE266_DID;
+               break;
+
+       case UNICHROME_K400:
+               viainfo.device_id = UNICHROME_K400_DID;
+               break;
+
+       case UNICHROME_K800:
+               viainfo.device_id = UNICHROME_K800_DID;
+               break;
+
+       case UNICHROME_PM800:
+               viainfo.device_id = UNICHROME_PM800_DID;
+               break;
+
+       case UNICHROME_CN700:
+               viainfo.device_id = UNICHROME_CN700_DID;
+               break;
+
+       case UNICHROME_CX700:
+               viainfo.device_id = UNICHROME_CX700_DID;
+               break;
+
+       case UNICHROME_K8M890:
+               viainfo.device_id = UNICHROME_K8M890_DID;
+               break;
+
+       case UNICHROME_P4M890:
+               viainfo.device_id = UNICHROME_P4M890_DID;
+               break;
+
+       case UNICHROME_P4M900:
+               viainfo.device_id = UNICHROME_P4M900_DID;
+               break;
+       }
+
+       viainfo.version = VERSION_MAJOR;
+       viainfo.revision = VERSION_MINOR;
+
+       if (copy_to_user((void __user *)arg, &viainfo, sizeof(viainfo)))
+               return -EFAULT;
+
+       return 0;
+}
+
+/* Hot-Plug Priority: DVI > CRT*/
+int viafb_ioctl_hotplug(int hres, int vres, int bpp)
+{
+       int DVIsense, status = 0;
+       DEBUG_MSG(KERN_INFO "viafb_ioctl_hotplug!!\n");
+
+       if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name !=
+               NON_TMDS_TRANSMITTER) {
+               DVIsense = viafb_dvi_sense();
+
+               if (DVIsense) {
+                       DEBUG_MSG(KERN_INFO "DVI Attached...\n");
+                       if (viafb_DeviceStatus != DVI_Device) {
+                               viafb_DVI_ON = 1;
+                               viafb_CRT_ON = 0;
+                               viafb_LCD_ON = 0;
+                               viafb_DeviceStatus = DVI_Device;
+                               return viafb_DeviceStatus;
+                       }
+                       status = 1;
+               } else
+                       DEBUG_MSG(KERN_INFO "DVI De-attached...\n");
+       }
+
+       if ((viafb_DeviceStatus != CRT_Device) && (status == 0)) {
+               viafb_CRT_ON = 1;
+               viafb_DVI_ON = 0;
+               viafb_LCD_ON = 0;
+
+               viafb_DeviceStatus = CRT_Device;
+               return viafb_DeviceStatus;
+       }
+
+       return 0;
+}
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
new file mode 100644 (file)
index 0000000..842fe30
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IOCTL_H__
+#define __IOCTL_H__
+
+#ifndef __user
+#define __user
+#endif
+
+/* VIAFB IOCTL definition */
+#define VIAFB_GET_INFO_SIZE            0x56494101      /* 'VIA\01' */
+#define VIAFB_GET_INFO                 0x56494102      /* 'VIA\02' */
+#define VIAFB_HOTPLUG                  0x56494103      /* 'VIA\03' */
+#define VIAFB_SET_HOTPLUG_FLAG         0x56494104      /* 'VIA\04' */
+#define VIAFB_GET_RESOLUTION           0x56494105      /* 'VIA\05' */
+#define VIAFB_GET_SAMM_INFO            0x56494107      /* 'VIA\07' */
+#define VIAFB_TURN_ON_OUTPUT_DEVICE     0x56494108     /* 'VIA\08' */
+#define VIAFB_TURN_OFF_OUTPUT_DEVICE    0x56494109     /* 'VIA\09' */
+#define VIAFB_SET_DEVICE               0x5649410A
+#define VIAFB_GET_DEVICE               0x5649410B
+#define VIAFB_GET_DRIVER_VERSION       0x56494112      /* 'VIA\12' */
+#define VIAFB_GET_CHIP_INFO            0x56494113      /* 'VIA\13' */
+#define VIAFB_SET_DEVICE_INFO           0x56494114
+#define VIAFB_GET_DEVICE_INFO           0x56494115
+
+#define VIAFB_GET_DEVICE_SUPPORT       0x56494118
+#define VIAFB_GET_DEVICE_CONNECT       0x56494119
+#define VIAFB_GET_PANEL_SUPPORT_EXPAND 0x5649411A
+#define VIAFB_GET_DRIVER_NAME          0x56494122
+#define VIAFB_GET_DEVICE_SUPPORT_STATE 0x56494123
+#define VIAFB_GET_GAMMA_LUT            0x56494124
+#define VIAFB_SET_GAMMA_LUT            0x56494125
+#define VIAFB_GET_GAMMA_SUPPORT_STATE  0x56494126
+#define VIAFB_SET_VIDEO_DEVICE         0x56494127
+#define VIAFB_GET_VIDEO_DEVICE         0x56494128
+#define VIAFB_SET_SECOND_MODE          0x56494129
+#define VIAFB_SYNC_SURFACE             0x56494130
+#define VIAFB_GET_DRIVER_CAPS          0x56494131
+#define VIAFB_GET_IGA_SCALING_INFO     0x56494132
+#define VIAFB_GET_PANEL_MAX_SIZE       0x56494133
+#define VIAFB_GET_PANEL_MAX_POSITION   0x56494134
+#define VIAFB_SET_PANEL_SIZE           0x56494135
+#define VIAFB_SET_PANEL_POSITION        0x56494136
+#define VIAFB_GET_PANEL_POSITION        0x56494137
+#define VIAFB_GET_PANEL_SIZE           0x56494138
+
+#define None_Device 0x00
+#define CRT_Device  0x01
+#define LCD_Device  0x02
+#define DVI_Device  0x08
+#define CRT2_Device 0x10
+#define LCD2_Device 0x40
+
+#define OP_LCD_CENTERING   0x01
+#define OP_LCD_PANEL_ID    0x02
+#define OP_LCD_MODE        0x03
+
+/*SAMM operation flag*/
+#define OP_SAMM            0x80
+
+#define LCD_PANEL_ID_MAXIMUM   22
+
+#define STATE_ON            0x1
+#define STATE_OFF           0x0
+#define STATE_DEFAULT       0xFFFF
+
+#define MAX_ACTIVE_DEV_NUM  2
+
+struct device_t {
+       unsigned short crt:1;
+       unsigned short dvi:1;
+       unsigned short lcd:1;
+       unsigned short samm:1;
+       unsigned short lcd_dsp_cent:1;
+       unsigned char lcd_mode:1;
+       unsigned short epia_dvi:1;
+       unsigned short lcd_dual_edge:1;
+       unsigned short lcd2:1;
+
+       unsigned short primary_dev;
+       unsigned char lcd_panel_id;
+       unsigned short xres, yres;
+       unsigned short xres1, yres1;
+       unsigned short refresh;
+       unsigned short bpp;
+       unsigned short refresh1;
+       unsigned short bpp1;
+       unsigned short sequence;
+       unsigned short bus_width;
+};
+
+struct viafb_ioctl_info {
+       u32 viafb_id;           /* for identifying viafb */
+#define VIAID       0x56494146 /* Identify myself with 'VIAF' */
+       u16 vendor_id;
+       u16 device_id;
+       u8 version;
+       u8 revision;
+       u8 reserved[246];       /* for future use */
+};
+
+struct viafb_ioctl_mode {
+       u32 xres;
+       u32 yres;
+       u32 refresh;
+       u32 bpp;
+       u32 xres_sec;
+       u32 yres_sec;
+       u32 virtual_xres_sec;
+       u32 virtual_yres_sec;
+       u32 refresh_sec;
+       u32 bpp_sec;
+};
+struct viafb_ioctl_samm {
+       u32 samm_status;
+       u32 size_prim;
+       u32 size_sec;
+       u32 mem_base;
+       u32 offset_sec;
+};
+
+struct viafb_driver_version {
+       int iMajorNum;
+       int iKernelNum;
+       int iOSNum;
+       int iMinorNum;
+};
+
+struct viafb_ioctl_lcd_attribute {
+       unsigned int panel_id;
+       unsigned int display_center;
+       unsigned int lcd_mode;
+};
+
+struct viafb_ioctl_setting {
+       /* Enable or disable active devices */
+       unsigned short device_flag;
+       /* Indicate which device should be turn on or turn off. */
+       unsigned short device_status;
+       unsigned int reserved;
+       /* Indicate which LCD's attribute can be changed. */
+       unsigned short lcd_operation_flag;
+       /* 1: SAMM ON  0: SAMM OFF */
+       unsigned short samm_status;
+       /* horizontal resolution of first device */
+       unsigned short first_dev_hor_res;
+       /* vertical resolution of first device */
+       unsigned short first_dev_ver_res;
+       /* horizontal resolution of second device */
+       unsigned short second_dev_hor_res;
+       /* vertical resolution of second device */
+       unsigned short second_dev_ver_res;
+       /* refresh rate of first device */
+       unsigned short first_dev_refresh;
+       /* bpp of first device */
+       unsigned short first_dev_bpp;
+       /* refresh rate of second device */
+       unsigned short second_dev_refresh;
+       /* bpp of second device */
+       unsigned short second_dev_bpp;
+       /* Indicate which device are primary display device. */
+       unsigned int primary_device;
+       /* Indicate which device will show video. only valid in duoview mode */
+       unsigned int video_device_status;
+       unsigned int struct_reserved[34];
+       struct viafb_ioctl_lcd_attribute lcd_attributes;
+};
+
+struct _UTFunctionCaps {
+       unsigned int dw3DScalingState;
+       unsigned int reserved[31];
+};
+
+struct _POSITIONVALUE {
+       unsigned int dwX;
+       unsigned int dwY;
+};
+
+struct _panel_size_pos_info {
+       unsigned int device_type;
+       int x;
+       int y;
+};
+
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+
+int viafb_ioctl_get_viafb_info(u_long arg);
+int viafb_ioctl_hotplug(int hres, int vres, int bpp);
+
+#endif /* __IOCTL_H__ */
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
new file mode 100644 (file)
index 0000000..6c7290a
--- /dev/null
@@ -0,0 +1,1821 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+#include "lcdtbl.h"
+
+static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = {
+       /* IGA2 Shadow Horizontal Total */
+       {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } },
+       /* IGA2 Shadow Horizontal Blank End */
+       {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } },
+       /* IGA2 Shadow Vertical Total */
+       {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } },
+       /* IGA2 Shadow Vertical Addressable Video */
+       {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } },
+       /* IGA2 Shadow Vertical Blank Start */
+       {IGA2_SHADOW_VER_BLANK_START_REG_NUM,
+        {{CR72, 0, 7}, {CR74, 4, 6} } },
+       /* IGA2 Shadow Vertical Blank End */
+       {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } },
+       /* IGA2 Shadow Vertical Sync Start */
+       {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } },
+       /* IGA2 Shadow Vertical Sync End */
+       {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }
+};
+
+static struct _lcd_scaling_factor lcd_scaling_factor = {
+       /* LCD Horizontal Scaling Factor Register */
+       {LCD_HOR_SCALING_FACTOR_REG_NUM,
+        {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
+       /* LCD Vertical Scaling Factor Register */
+       {LCD_VER_SCALING_FACTOR_REG_NUM,
+        {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
+};
+static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
+       /* LCD Horizontal Scaling Factor Register */
+       {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
+       /* LCD Vertical Scaling Factor Register */
+       {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
+};
+
+static int check_lvds_chip(int device_id_subaddr, int device_id);
+static bool lvds_identify_integratedlvds(void);
+static int fp_id_to_vindex(int panel_id);
+static int lvds_register_read(int index);
+static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
+                     int panel_vres);
+static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
+       int panel_id);
+static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
+       int panel_id);
+static void load_lcd_patch_regs(int set_hres, int set_vres,
+       int panel_id, int set_iga);
+static void via_pitch_alignment_patch_lcd(
+       struct lvds_setting_information *plvds_setting_info,
+                                  struct lvds_chip_information
+                                  *plvds_chip_info);
+static void lcd_patch_skew_dvp0(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info);
+static void lcd_patch_skew_dvp1(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info);
+static void lcd_patch_skew(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
+
+static void integrated_lvds_disable(struct lvds_setting_information
+                            *plvds_setting_info,
+                            struct lvds_chip_information *plvds_chip_info);
+static void integrated_lvds_enable(struct lvds_setting_information
+                           *plvds_setting_info,
+                           struct lvds_chip_information *plvds_chip_info);
+static void lcd_powersequence_off(void);
+static void lcd_powersequence_on(void);
+static void fill_lcd_format(void);
+static void check_diport_of_integrated_lvds(
+       struct lvds_chip_information *plvds_chip_info,
+                                    struct lvds_setting_information
+                                    *plvds_setting_info);
+static struct display_timing lcd_centering_timging(struct display_timing
+                                           mode_crt_reg,
+                                          struct display_timing panel_crt_reg);
+static void load_crtc_shadow_timing(struct display_timing mode_timing,
+                            struct display_timing panel_timing);
+static void viafb_load_scaling_factor_for_p4m900(int set_hres,
+       int set_vres, int panel_hres, int panel_vres);
+
+static int check_lvds_chip(int device_id_subaddr, int device_id)
+{
+       if (lvds_register_read(device_id_subaddr) == device_id)
+               return OK;
+       else
+               return FAIL;
+}
+
+void viafb_init_lcd_size(void)
+{
+       DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
+       DEBUG_MSG(KERN_INFO
+               "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
+               viaparinfo->lvds_setting_info->get_lcd_size_method);
+
+       switch (viaparinfo->lvds_setting_info->get_lcd_size_method) {
+       case GET_LCD_SIZE_BY_SYSTEM_BIOS:
+               break;
+       case GET_LCD_SZIE_BY_HW_STRAPPING:
+               break;
+       case GET_LCD_SIZE_BY_VGA_BIOS:
+               DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
+               viaparinfo->lvds_setting_info->lcd_panel_size =
+                   fp_id_to_vindex(viafb_lcd_panel_id);
+               DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
+                         viaparinfo->lvds_setting_info->lcd_panel_id);
+               DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
+                         viaparinfo->lvds_setting_info->lcd_panel_size);
+               break;
+       case GET_LCD_SIZE_BY_USER_SETTING:
+               DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
+               viaparinfo->lvds_setting_info->lcd_panel_size =
+                   fp_id_to_vindex(viafb_lcd_panel_id);
+               DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
+                         viaparinfo->lvds_setting_info->lcd_panel_id);
+               DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
+                         viaparinfo->lvds_setting_info->lcd_panel_size);
+               break;
+       default:
+               DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID1_800X600;
+               viaparinfo->lvds_setting_info->lcd_panel_size =
+                   fp_id_to_vindex(LCD_PANEL_ID1_800X600);
+       }
+       viaparinfo->lvds_setting_info2->lcd_panel_id =
+               viaparinfo->lvds_setting_info->lcd_panel_id;
+       viaparinfo->lvds_setting_info2->lcd_panel_size =
+               viaparinfo->lvds_setting_info->lcd_panel_size;
+       viaparinfo->lvds_setting_info2->lcd_panel_hres =
+               viaparinfo->lvds_setting_info->lcd_panel_hres;
+       viaparinfo->lvds_setting_info2->lcd_panel_vres =
+               viaparinfo->lvds_setting_info->lcd_panel_vres;
+       viaparinfo->lvds_setting_info2->device_lcd_dualedge =
+           viaparinfo->lvds_setting_info->device_lcd_dualedge;
+       viaparinfo->lvds_setting_info2->LCDDithering =
+               viaparinfo->lvds_setting_info->LCDDithering;
+}
+
+static bool lvds_identify_integratedlvds(void)
+{
+       if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
+               /* Two dual channel LCD (Internal LVDS + External LVDS): */
+               /* If we have an external LVDS, such as VT1636, we should
+                  have its chip ID already. */
+               if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+                       viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
+                           INTEGRATED_LVDS;
+                       DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\
+                                 (Internal LVDS + External LVDS)\n");
+               } else {
+                       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+                           INTEGRATED_LVDS;
+                       DEBUG_MSG(KERN_INFO "Not found external LVDS,\
+                                 so can't support two dual channel LVDS!\n");
+               }
+       } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
+               /* Two single channel LCD (Internal LVDS + Internal LVDS): */
+               viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+               INTEGRATED_LVDS;
+               viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
+                       INTEGRATED_LVDS;
+               DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\
+                         (Internal LVDS + Internal LVDS)\n");
+       } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
+               /* If we have found external LVDS, just use it,
+                  otherwise, we will use internal LVDS as default. */
+               if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+                       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+                           INTEGRATED_LVDS;
+                       DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
+               }
+       } else {
+               viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+                       NON_LVDS_TRANSMITTER;
+               DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
+               return false;
+       }
+
+       return true;
+}
+
+int viafb_lvds_trasmitter_identify(void)
+{
+       viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX;
+       if (viafb_lvds_identify_vt1636()) {
+               viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
+               DEBUG_MSG(KERN_INFO
+                         "Found VIA VT1636 LVDS on port i2c 0x31 \n");
+       } else {
+               viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
+               if (viafb_lvds_identify_vt1636()) {
+                       viaparinfo->chip_info->lvds_chip_info.i2c_port =
+                               GPIOPORTINDEX;
+                       DEBUG_MSG(KERN_INFO
+                                 "Found VIA VT1636 LVDS on port gpio 0x2c \n");
+               }
+       }
+
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
+               lvds_identify_integratedlvds();
+
+       if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
+               return true;
+       /* Check for VT1631: */
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
+               VT1631_LVDS_I2C_ADDR;
+
+       if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) {
+               DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
+               DEBUG_MSG(KERN_INFO "\n %2d",
+                         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
+               DEBUG_MSG(KERN_INFO "\n %2d",
+                         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
+               return OK;
+       }
+
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+               NON_LVDS_TRANSMITTER;
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
+               VT1631_LVDS_I2C_ADDR;
+       return FAIL;
+}
+
+static int fp_id_to_vindex(int panel_id)
+{
+       DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
+
+       if (panel_id > LCD_PANEL_ID_MAXIMUM)
+               viafb_lcd_panel_id = panel_id =
+               viafb_read_reg(VIACR, CR3F) & 0x0F;
+
+       switch (panel_id) {
+       case 0x0:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID0_640X480;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_640X480;
+               break;
+       case 0x1:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID1_800X600;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_800X600;
+               break;
+       case 0x2:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID2_1024X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1024X768;
+               break;
+       case 0x3:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID3_1280X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1280X768;
+               break;
+       case 0x4:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID4_1280X1024;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1280X1024;
+               break;
+       case 0x5:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID5_1400X1050;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1400X1050;
+               break;
+       case 0x6:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID6_1600X1200;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1600X1200;
+               break;
+       case 0x8:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_IDA_800X480;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_800X480;
+               break;
+       case 0x9:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID2_1024X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1024X768;
+               break;
+       case 0xA:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID2_1024X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1024X768;
+               break;
+       case 0xB:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID2_1024X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1024X768;
+               break;
+       case 0xC:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID3_1280X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1280X768;
+               break;
+       case 0xD:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID4_1280X1024;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1280X1024;
+               break;
+       case 0xE:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID5_1400X1050;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1400X1050;
+               break;
+       case 0xF:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID6_1600X1200;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1600X1200;
+               break;
+       case 0x10:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID7_1366X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1368X768;
+               break;
+       case 0x11:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID8_1024X600;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1024X600;
+               break;
+       case 0x12:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID3_1280X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1280X768;
+               break;
+       case 0x13:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID9_1280X800;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_1280X800;
+               break;
+       case 0x14:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_IDB_1360X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1360X768;
+               break;
+       case 0x15:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID3_1280X768;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+               viaparinfo->lvds_setting_info->LCDDithering = 0;
+               return VIA_RES_1280X768;
+               break;
+       case 0x16:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_IDC_480X640;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_480X640;
+               break;
+       default:
+               viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
+               viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
+               viaparinfo->lvds_setting_info->lcd_panel_id =
+                       LCD_PANEL_ID1_800X600;
+               viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+               viaparinfo->lvds_setting_info->LCDDithering = 1;
+               return VIA_RES_800X600;
+       }
+}
+
+static int lvds_register_read(int index)
+{
+       u8 data;
+
+       viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
+       viafb_i2c_readbyte((u8) viaparinfo->chip_info->
+           lvds_chip_info.lvds_chip_slave_addr,
+                       (u8) index, &data);
+       return data;
+}
+
+static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
+                     int panel_vres)
+{
+       int reg_value = 0;
+       int viafb_load_reg_num;
+       struct io_register *reg = NULL;
+
+       DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
+
+       /* LCD Scaling Enable */
+       viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
+       if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
+               viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
+                                              panel_hres, panel_vres);
+               return;
+       }
+
+       /* Check if expansion for horizontal */
+       if (set_hres != panel_hres) {
+               /* Load Horizontal Scaling Factor */
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CLE266:
+               case UNICHROME_K400:
+                       reg_value =
+                           CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
+                       viafb_load_reg_num =
+                           lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
+                           reg_num;
+                       reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_num, reg, VIACR);
+                       break;
+               case UNICHROME_K800:
+               case UNICHROME_PM800:
+               case UNICHROME_CN700:
+               case UNICHROME_CX700:
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M890:
+                       reg_value =
+                           K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
+                       /* Horizontal scaling enabled */
+                       viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
+                       viafb_load_reg_num =
+                           lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
+                       reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_num, reg, VIACR);
+                       break;
+               }
+
+               DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
+       } else {
+               /* Horizontal scaling disabled */
+               viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
+       }
+
+       /* Check if expansion for vertical */
+       if (set_vres != panel_vres) {
+               /* Load Vertical Scaling Factor */
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CLE266:
+               case UNICHROME_K400:
+                       reg_value =
+                           CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
+                       viafb_load_reg_num =
+                           lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
+                           reg_num;
+                       reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_num, reg, VIACR);
+                       break;
+               case UNICHROME_K800:
+               case UNICHROME_PM800:
+               case UNICHROME_CN700:
+               case UNICHROME_CX700:
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M890:
+                       reg_value =
+                           K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
+                       /* Vertical scaling enabled */
+                       viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
+                       viafb_load_reg_num =
+                           lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
+                       reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_num, reg, VIACR);
+                       break;
+               }
+
+               DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
+       } else {
+               /* Vertical scaling disabled */
+               viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
+       }
+}
+
+static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
+       int panel_id)
+{
+       int vmode_index;
+       int reg_num = 0;
+       struct io_reg *lcd_patch_reg = NULL;
+
+       if (viaparinfo->lvds_setting_info->iga_path == IGA2)
+               vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
+       else
+               vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+       switch (panel_id) {
+               /* LCD 800x600 */
+       case LCD_PANEL_ID1_800X600:
+               switch (vmode_index) {
+               case VIA_RES_640X400:
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6;
+                       lcd_patch_reg = K400_LCD_RES_6X4_8X6;
+                       break;
+               case VIA_RES_720X480:
+               case VIA_RES_720X576:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6;
+                       lcd_patch_reg = K400_LCD_RES_7X4_8X6;
+                       break;
+               }
+               break;
+
+               /* LCD 1024x768 */
+       case LCD_PANEL_ID2_1024X768:
+               switch (vmode_index) {
+               case VIA_RES_640X400:
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7;
+                       lcd_patch_reg = K400_LCD_RES_6X4_10X7;
+                       break;
+               case VIA_RES_720X480:
+               case VIA_RES_720X576:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7;
+                       lcd_patch_reg = K400_LCD_RES_7X4_10X7;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7;
+                       lcd_patch_reg = K400_LCD_RES_8X6_10X7;
+                       break;
+               }
+               break;
+
+               /* LCD 1280x1024 */
+       case LCD_PANEL_ID4_1280X1024:
+               switch (vmode_index) {
+               case VIA_RES_640X400:
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10;
+                       lcd_patch_reg = K400_LCD_RES_6X4_12X10;
+                       break;
+               case VIA_RES_720X480:
+               case VIA_RES_720X576:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10;
+                       lcd_patch_reg = K400_LCD_RES_7X4_12X10;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10;
+                       lcd_patch_reg = K400_LCD_RES_8X6_12X10;
+                       break;
+               case VIA_RES_1024X768:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10;
+                       lcd_patch_reg = K400_LCD_RES_10X7_12X10;
+                       break;
+
+               }
+               break;
+
+               /* LCD 1400x1050 */
+       case LCD_PANEL_ID5_1400X1050:
+               switch (vmode_index) {
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10;
+                       lcd_patch_reg = K400_LCD_RES_6X4_14X10;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10;
+                       lcd_patch_reg = K400_LCD_RES_8X6_14X10;
+                       break;
+               case VIA_RES_1024X768:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10;
+                       lcd_patch_reg = K400_LCD_RES_10X7_14X10;
+                       break;
+               case VIA_RES_1280X768:
+               case VIA_RES_1280X800:
+               case VIA_RES_1280X960:
+               case VIA_RES_1280X1024:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10;
+                       lcd_patch_reg = K400_LCD_RES_12X10_14X10;
+                       break;
+               }
+               break;
+
+               /* LCD 1600x1200 */
+       case LCD_PANEL_ID6_1600X1200:
+               switch (vmode_index) {
+               case VIA_RES_640X400:
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12;
+                       lcd_patch_reg = K400_LCD_RES_6X4_16X12;
+                       break;
+               case VIA_RES_720X480:
+               case VIA_RES_720X576:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12;
+                       lcd_patch_reg = K400_LCD_RES_7X4_16X12;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12;
+                       lcd_patch_reg = K400_LCD_RES_8X6_16X12;
+                       break;
+               case VIA_RES_1024X768:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12;
+                       lcd_patch_reg = K400_LCD_RES_10X7_16X12;
+                       break;
+               case VIA_RES_1280X768:
+               case VIA_RES_1280X800:
+               case VIA_RES_1280X960:
+               case VIA_RES_1280X1024:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12;
+                       lcd_patch_reg = K400_LCD_RES_12X10_16X12;
+                       break;
+               }
+               break;
+
+               /* LCD 1366x768 */
+       case LCD_PANEL_ID7_1366X768:
+               switch (vmode_index) {
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7;
+                       lcd_patch_reg = K400_LCD_RES_6X4_1366X7;
+                       break;
+               case VIA_RES_720X480:
+               case VIA_RES_720X576:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7;
+                       lcd_patch_reg = K400_LCD_RES_7X4_1366X7;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7;
+                       lcd_patch_reg = K400_LCD_RES_8X6_1366X7;
+                       break;
+               case VIA_RES_1024X768:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7;
+                       lcd_patch_reg = K400_LCD_RES_10X7_1366X7;
+                       break;
+               case VIA_RES_1280X768:
+               case VIA_RES_1280X800:
+               case VIA_RES_1280X960:
+               case VIA_RES_1280X1024:
+                       reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7;
+                       lcd_patch_reg = K400_LCD_RES_12X10_1366X7;
+                       break;
+               }
+               break;
+
+               /* LCD 1360x768 */
+       case LCD_PANEL_IDB_1360X768:
+               break;
+       }
+       if (reg_num != 0) {
+               /* H.W. Reset : ON */
+               viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+
+               viafb_write_regx(lcd_patch_reg, reg_num);
+
+               /* H.W. Reset : OFF */
+               viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+
+               /* Reset PLL */
+               viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
+               viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
+
+               /* Fire! */
+               outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
+       }
+}
+
+static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
+       int panel_id)
+{
+       int vmode_index;
+       int reg_num = 0;
+       struct io_reg *lcd_patch_reg = NULL;
+
+       if (viaparinfo->lvds_setting_info->iga_path == IGA2)
+               vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
+       else
+               vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+
+       switch (panel_id) {
+       case LCD_PANEL_ID5_1400X1050:
+               switch (vmode_index) {
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10;
+                       lcd_patch_reg = P880_LCD_RES_6X4_14X10;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10;
+                       lcd_patch_reg = P880_LCD_RES_8X6_14X10;
+                       break;
+               }
+               break;
+       case LCD_PANEL_ID6_1600X1200:
+               switch (vmode_index) {
+               case VIA_RES_640X400:
+               case VIA_RES_640X480:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12;
+                       lcd_patch_reg = P880_LCD_RES_6X4_16X12;
+                       break;
+               case VIA_RES_720X480:
+               case VIA_RES_720X576:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12;
+                       lcd_patch_reg = P880_LCD_RES_7X4_16X12;
+                       break;
+               case VIA_RES_800X600:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12;
+                       lcd_patch_reg = P880_LCD_RES_8X6_16X12;
+                       break;
+               case VIA_RES_1024X768:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12;
+                       lcd_patch_reg = P880_LCD_RES_10X7_16X12;
+                       break;
+               case VIA_RES_1280X768:
+               case VIA_RES_1280X960:
+               case VIA_RES_1280X1024:
+                       reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12;
+                       lcd_patch_reg = P880_LCD_RES_12X10_16X12;
+                       break;
+               }
+               break;
+
+       }
+       if (reg_num != 0) {
+               /* H.W. Reset : ON */
+               viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+
+               viafb_write_regx(lcd_patch_reg, reg_num);
+
+               /* H.W. Reset : OFF */
+               viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+
+               /* Reset PLL */
+               viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
+               viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
+
+               /* Fire! */
+               outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
+       }
+}
+
+static void load_lcd_patch_regs(int set_hres, int set_vres,
+       int panel_id, int set_iga)
+{
+       int vmode_index;
+
+       if (viaparinfo->lvds_setting_info->iga_path == IGA2)
+               vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
+       else
+               vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+
+       viafb_unlock_crt();
+
+       /* Patch for simultaneous & Expansion */
+       if ((set_iga == IGA1_IGA2) &&
+               (viaparinfo->lvds_setting_info->display_method ==
+           LCD_EXPANDSION)) {
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CLE266:
+               case UNICHROME_K400:
+                       load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id);
+                       break;
+               case UNICHROME_K800:
+                       break;
+               case UNICHROME_PM800:
+               case UNICHROME_CN700:
+               case UNICHROME_CX700:
+                       load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id);
+               }
+       }
+
+       viafb_lock_crt();
+}
+
+static void via_pitch_alignment_patch_lcd(
+       struct lvds_setting_information *plvds_setting_info,
+                                  struct lvds_chip_information
+                                  *plvds_chip_info)
+{
+       unsigned char cr13, cr35, cr65, cr66, cr67;
+       unsigned long dwScreenPitch = 0;
+       unsigned long dwPitch;
+
+       dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
+       if (dwPitch & 0x1F) {
+               dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
+               if (plvds_setting_info->iga_path == IGA2) {
+                       if (plvds_setting_info->bpp > 8) {
+                               cr66 = (unsigned char)(dwScreenPitch & 0xFF);
+                               viafb_write_reg(CR66, VIACR, cr66);
+                               cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
+                               cr67 |=
+                                   (unsigned
+                                    char)((dwScreenPitch & 0x300) >> 8);
+                               viafb_write_reg(CR67, VIACR, cr67);
+                       }
+
+                       /* Fetch Count */
+                       cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
+                       cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
+                       viafb_write_reg(CR67, VIACR, cr67);
+                       cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
+                       cr65 += 2;
+                       viafb_write_reg(CR65, VIACR, cr65);
+               } else {
+                       if (plvds_setting_info->bpp > 8) {
+                               cr13 = (unsigned char)(dwScreenPitch & 0xFF);
+                               viafb_write_reg(CR13, VIACR, cr13);
+                               cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
+                               cr35 |=
+                                   (unsigned
+                                    char)((dwScreenPitch & 0x700) >> 3);
+                               viafb_write_reg(CR35, VIACR, cr35);
+                       }
+               }
+       }
+}
+static void lcd_patch_skew_dvp0(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info)
+{
+       if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_P4M900:
+                       viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
+                                                   plvds_chip_info);
+                       break;
+               case UNICHROME_P4M890:
+                       viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
+                                                   plvds_chip_info);
+                       break;
+               }
+       }
+}
+static void lcd_patch_skew_dvp1(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info)
+{
+       if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CX700:
+                       viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
+                                                   plvds_chip_info);
+                       break;
+               }
+       }
+}
+static void lcd_patch_skew(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
+{
+       DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
+       switch (plvds_chip_info->output_interface) {
+       case INTERFACE_DVP0:
+               lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
+               break;
+       case INTERFACE_DVP1:
+               lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
+               break;
+       case INTERFACE_DFP_LOW:
+               if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
+                       viafb_write_reg_mask(CR99, VIACR, 0x08,
+                                      BIT0 + BIT1 + BIT2 + BIT3);
+               }
+               break;
+       }
+}
+
+/* LCD Set Mode */
+void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
+                 struct lvds_setting_information *plvds_setting_info,
+                 struct lvds_chip_information *plvds_chip_info)
+{
+       int video_index = plvds_setting_info->lcd_panel_size;
+       int set_iga = plvds_setting_info->iga_path;
+       int mode_bpp = plvds_setting_info->bpp;
+       int viafb_load_reg_num = 0;
+       int reg_value = 0;
+       int set_hres, set_vres;
+       int panel_hres, panel_vres;
+       u32 pll_D_N;
+       int offset;
+       struct io_register *reg = NULL;
+       struct display_timing mode_crt_reg, panel_crt_reg;
+       struct crt_mode_table *panel_crt_table = NULL;
+       struct VideoModeTable *vmode_tbl = NULL;
+
+       DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
+       /* Get mode table */
+       mode_crt_reg = mode_crt_table->crtc;
+       /* Get panel table Pointer */
+       vmode_tbl = viafb_get_modetbl_pointer(video_index);
+       panel_crt_table = vmode_tbl->crtc;
+       panel_crt_reg = panel_crt_table->crtc;
+       DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
+       set_hres = plvds_setting_info->h_active;
+       set_vres = plvds_setting_info->v_active;
+       panel_hres = plvds_setting_info->lcd_panel_hres;
+       panel_vres = plvds_setting_info->lcd_panel_vres;
+       if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
+               viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
+       plvds_setting_info->vclk = panel_crt_table->clk;
+       if (set_iga == IGA1) {
+               /* IGA1 doesn't have LCD scaling, so set it as centering. */
+               viafb_load_crtc_timing(lcd_centering_timging
+                                (mode_crt_reg, panel_crt_reg), IGA1);
+       } else {
+               /* Expansion */
+               if ((plvds_setting_info->display_method ==
+                    LCD_EXPANDSION) & ((set_hres != panel_hres)
+                                       || (set_vres != panel_vres))) {
+                       /* expansion timing IGA2 loaded panel set timing*/
+                       viafb_load_crtc_timing(panel_crt_reg, IGA2);
+                       DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
+                       load_lcd_scaling(set_hres, set_vres, panel_hres,
+                                        panel_vres);
+                       DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
+               } else {        /* Centering */
+                       /* centering timing IGA2 always loaded panel
+                          and mode releative timing */
+                       viafb_load_crtc_timing(lcd_centering_timging
+                                        (mode_crt_reg, panel_crt_reg), IGA2);
+                       viafb_write_reg_mask(CR79, VIACR, 0x00,
+                               BIT0 + BIT1 + BIT2);
+                       /* LCD scaling disabled */
+               }
+       }
+
+       if (set_iga == IGA1_IGA2) {
+               load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg);
+               /* Fill shadow registers */
+
+               switch (plvds_setting_info->lcd_panel_id) {
+               case LCD_PANEL_ID0_640X480:
+                       offset = 80;
+                       break;
+               case LCD_PANEL_ID1_800X600:
+               case LCD_PANEL_IDA_800X480:
+                       offset = 110;
+                       break;
+               case LCD_PANEL_ID2_1024X768:
+                       offset = 150;
+                       break;
+               case LCD_PANEL_ID3_1280X768:
+               case LCD_PANEL_ID4_1280X1024:
+               case LCD_PANEL_ID5_1400X1050:
+               case LCD_PANEL_ID9_1280X800:
+                       offset = 190;
+                       break;
+               case LCD_PANEL_ID6_1600X1200:
+                       offset = 250;
+                       break;
+               case LCD_PANEL_ID7_1366X768:
+               case LCD_PANEL_IDB_1360X768:
+                       offset = 212;
+                       break;
+               default:
+                       offset = 140;
+                       break;
+               }
+
+               /* Offset for simultaneous */
+               reg_value = offset;
+               viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
+               reg = offset_reg.iga2_offset_reg.reg;
+               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+               DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
+               viafb_load_fetch_count_reg(set_hres, 4, IGA2);
+               /* Fetch count for simultaneous */
+       } else {                /* SAMM */
+               /* Offset for IGA2 only */
+               viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga);
+               /* Fetch count for IGA2 only */
+               viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
+
+               if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+                   && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
+                       viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
+
+               viafb_set_color_depth(mode_bpp / 8, set_iga);
+       }
+
+       fill_lcd_format();
+
+       pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
+       DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
+       viafb_set_vclock(pll_D_N, set_iga);
+
+       viafb_set_output_path(DEVICE_LCD, set_iga,
+               plvds_chip_info->output_interface);
+       lcd_patch_skew(plvds_setting_info, plvds_chip_info);
+
+       /* If K8M800, enable LCD Prefetch Mode. */
+       if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
+           || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
+               viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
+
+       load_lcd_patch_regs(set_hres, set_vres,
+                           plvds_setting_info->lcd_panel_id, set_iga);
+
+       DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n");
+
+       /* Patch for non 32bit alignment mode */
+       via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
+}
+
+static void integrated_lvds_disable(struct lvds_setting_information
+                            *plvds_setting_info,
+                            struct lvds_chip_information *plvds_chip_info)
+{
+       bool turn_off_first_powersequence = false;
+       bool turn_off_second_powersequence = false;
+       if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
+               turn_off_first_powersequence = true;
+       if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
+               turn_off_first_powersequence = true;
+       if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
+               turn_off_second_powersequence = true;
+       if (turn_off_second_powersequence) {
+               /* Use second power sequence control: */
+
+               /* Turn off power sequence. */
+               viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
+
+               /* Turn off back light. */
+               viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
+       }
+       if (turn_off_first_powersequence) {
+               /* Use first power sequence control: */
+
+               /* Turn off power sequence. */
+               viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
+
+               /* Turn off back light. */
+               viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
+       }
+
+       /* Turn DFP High/Low Pad off. */
+       viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3);
+
+       /* Power off LVDS channel. */
+       switch (plvds_chip_info->output_interface) {
+       case INTERFACE_LVDS0:
+               {
+                       viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
+                       break;
+               }
+
+       case INTERFACE_LVDS1:
+               {
+                       viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
+                       break;
+               }
+
+       case INTERFACE_LVDS0LVDS1:
+               {
+                       viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
+                       break;
+               }
+       }
+}
+
+static void integrated_lvds_enable(struct lvds_setting_information
+                           *plvds_setting_info,
+                           struct lvds_chip_information *plvds_chip_info)
+{
+       bool turn_on_first_powersequence = false;
+       bool turn_on_second_powersequence = false;
+
+       DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
+                 plvds_chip_info->output_interface);
+       if (plvds_setting_info->lcd_mode == LCD_SPWG)
+               viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
+        else
+               viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
+       if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
+               turn_on_first_powersequence = true;
+       if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
+               turn_on_first_powersequence = true;
+       if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
+               turn_on_second_powersequence = true;
+
+       if (turn_on_second_powersequence) {
+               /* Use second power sequence control: */
+
+               /* Use hardware control power sequence. */
+               viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
+
+               /* Turn on back light. */
+               viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
+
+               /* Turn on hardware power sequence. */
+               viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
+       }
+       if (turn_on_first_powersequence) {
+               /* Use first power sequence control: */
+
+               /* Use hardware control power sequence. */
+               viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
+
+               /* Turn on back light. */
+               viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
+
+               /* Turn on hardware power sequence. */
+               viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+       }
+
+       /* Turn DFP High/Low pad on. */
+       viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3);
+
+       /* Power on LVDS channel. */
+       switch (plvds_chip_info->output_interface) {
+       case INTERFACE_LVDS0:
+               {
+                       viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
+                       break;
+               }
+
+       case INTERFACE_LVDS1:
+               {
+                       viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
+                       break;
+               }
+
+       case INTERFACE_LVDS0LVDS1:
+               {
+                       viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
+                       break;
+               }
+       }
+}
+
+void viafb_lcd_disable(void)
+{
+
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+               lcd_powersequence_off();
+               /* DI1 pad off */
+               viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
+       } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+               if (viafb_LCD2_ON
+                   && (INTEGRATED_LVDS ==
+                       viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
+                       integrated_lvds_disable(viaparinfo->lvds_setting_info,
+                               &viaparinfo->chip_info->lvds_chip_info2);
+               if (INTEGRATED_LVDS ==
+                       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
+                       integrated_lvds_disable(viaparinfo->lvds_setting_info,
+                               &viaparinfo->chip_info->lvds_chip_info);
+               if (VT1636_LVDS == viaparinfo->chip_info->
+                       lvds_chip_info.lvds_chip_name)
+                       viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
+                               &viaparinfo->chip_info->lvds_chip_info);
+       } else if (VT1636_LVDS ==
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+               viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
+                                   &viaparinfo->chip_info->lvds_chip_info);
+       } else {
+               /* DFP-HL pad off          */
+               viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F);
+               /* Backlight off           */
+               viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
+               /* 24 bit DI data paht off */
+               viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
+               /* Simultaneout disabled   */
+               viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
+       }
+
+       /* Disable expansion bit   */
+       viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
+       /* CRT path set to IGA1    */
+       viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40);
+       /* Simultaneout disabled   */
+       viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
+       /* IGA2 path disabled      */
+       viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
+
+}
+
+void viafb_lcd_enable(void)
+{
+       if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+               /* DI1 pad on */
+               viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
+               lcd_powersequence_on();
+       } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+               if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
+                       viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
+                       integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
+                               &viaparinfo->chip_info->lvds_chip_info2);
+               if (INTEGRATED_LVDS ==
+                       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
+                       integrated_lvds_enable(viaparinfo->lvds_setting_info,
+                               &viaparinfo->chip_info->lvds_chip_info);
+               if (VT1636_LVDS == viaparinfo->chip_info->
+                       lvds_chip_info.lvds_chip_name)
+                       viafb_enable_lvds_vt1636(viaparinfo->
+                       lvds_setting_info, &viaparinfo->chip_info->
+                       lvds_chip_info);
+       } else if (VT1636_LVDS ==
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+               viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
+                                  &viaparinfo->chip_info->lvds_chip_info);
+       } else {
+               /* DFP-HL pad on           */
+               viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F);
+               /* Backlight on            */
+               viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
+               /* 24 bit DI data paht on  */
+               viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
+
+               /* Set data source selection bit by iga path */
+               if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
+                       /* DFP-H set to IGA1       */
+                       viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10);
+                       /* DFP-L set to IGA1       */
+                       viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10);
+               } else {
+                       /* DFP-H set to IGA2       */
+                       viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10);
+                       /* DFP-L set to IGA2       */
+                       viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10);
+               }
+               /* LCD enabled             */
+               viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
+       }
+
+       if ((viaparinfo->lvds_setting_info->iga_path == IGA1)
+           || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) {
+               /* CRT path set to IGA2    */
+               viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
+               /* IGA2 path disabled      */
+               viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
+               /* IGA2 path enabled       */
+       } else {                /* IGA2 */
+               viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80);
+       }
+
+}
+
+static void lcd_powersequence_off(void)
+{
+       int i, mask, data;
+
+       /* Software control power sequence */
+       viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
+
+       for (i = 0; i < 3; i++) {
+               mask = PowerSequenceOff[0][i];
+               data = PowerSequenceOff[1][i] & mask;
+               viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
+               udelay(PowerSequenceOff[2][i]);
+       }
+
+       /* Disable LCD */
+       viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
+}
+
+static void lcd_powersequence_on(void)
+{
+       int i, mask, data;
+
+       /* Software control power sequence */
+       viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
+
+       /* Enable LCD */
+       viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
+
+       for (i = 0; i < 3; i++) {
+               mask = PowerSequenceOn[0][i];
+               data = PowerSequenceOn[1][i] & mask;
+               viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
+               udelay(PowerSequenceOn[2][i]);
+       }
+
+       udelay(1);
+}
+
+static void fill_lcd_format(void)
+{
+       u8 bdithering = 0, bdual = 0;
+
+       if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
+               bdual = BIT4;
+       if (viaparinfo->lvds_setting_info->LCDDithering)
+               bdithering = BIT0;
+       /* Dual & Dithering */
+       viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
+}
+
+static void check_diport_of_integrated_lvds(
+       struct lvds_chip_information *plvds_chip_info,
+                                    struct lvds_setting_information
+                                    *plvds_setting_info)
+{
+       /* Determine LCD DI Port by hardware layout. */
+       switch (viafb_display_hardware_layout) {
+       case HW_LAYOUT_LCD_ONLY:
+               {
+                       if (plvds_setting_info->device_lcd_dualedge) {
+                               plvds_chip_info->output_interface =
+                                   INTERFACE_LVDS0LVDS1;
+                       } else {
+                               plvds_chip_info->output_interface =
+                                   INTERFACE_LVDS0;
+                       }
+
+                       break;
+               }
+
+       case HW_LAYOUT_DVI_ONLY:
+               {
+                       plvds_chip_info->output_interface = INTERFACE_NONE;
+                       break;
+               }
+
+       case HW_LAYOUT_LCD1_LCD2:
+       case HW_LAYOUT_LCD_EXTERNAL_LCD2:
+               {
+                       plvds_chip_info->output_interface =
+                           INTERFACE_LVDS0LVDS1;
+                       break;
+               }
+
+       case HW_LAYOUT_LCD_DVI:
+               {
+                       plvds_chip_info->output_interface = INTERFACE_LVDS1;
+                       break;
+               }
+
+       default:
+               {
+                       plvds_chip_info->output_interface = INTERFACE_LVDS1;
+                       break;
+               }
+       }
+
+       DEBUG_MSG(KERN_INFO
+                 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
+                 viafb_display_hardware_layout,
+                 plvds_chip_info->output_interface);
+}
+
+void viafb_init_lvds_output_interface(struct lvds_chip_information
+                               *plvds_chip_info,
+                               struct lvds_setting_information
+                               *plvds_setting_info)
+{
+       if (INTERFACE_NONE != plvds_chip_info->output_interface) {
+               /*Do nothing, lcd port is specified by module parameter */
+               return;
+       }
+
+       switch (plvds_chip_info->lvds_chip_name) {
+
+       case VT1636_LVDS:
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_CX700:
+                       plvds_chip_info->output_interface = INTERFACE_DVP1;
+                       break;
+               case UNICHROME_CN700:
+                       plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
+                       break;
+               default:
+                       plvds_chip_info->output_interface = INTERFACE_DVP0;
+                       break;
+               }
+               break;
+
+       case INTEGRATED_LVDS:
+               check_diport_of_integrated_lvds(plvds_chip_info,
+                                               plvds_setting_info);
+               break;
+
+       default:
+               switch (viaparinfo->chip_info->gfx_chip_name) {
+               case UNICHROME_K8M890:
+               case UNICHROME_P4M900:
+               case UNICHROME_P4M890:
+                       plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
+                       break;
+               default:
+                       plvds_chip_info->output_interface = INTERFACE_DFP;
+                       break;
+               }
+               break;
+       }
+}
+
+static struct display_timing lcd_centering_timging(struct display_timing
+                                           mode_crt_reg,
+                                           struct display_timing panel_crt_reg)
+{
+       struct display_timing crt_reg;
+
+       crt_reg.hor_total = panel_crt_reg.hor_total;
+       crt_reg.hor_addr = mode_crt_reg.hor_addr;
+       crt_reg.hor_blank_start =
+           (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 +
+           crt_reg.hor_addr;
+       crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end;
+       crt_reg.hor_sync_start =
+           (panel_crt_reg.hor_sync_start -
+            panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start;
+       crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end;
+
+       crt_reg.ver_total = panel_crt_reg.ver_total;
+       crt_reg.ver_addr = mode_crt_reg.ver_addr;
+       crt_reg.ver_blank_start =
+           (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 +
+           crt_reg.ver_addr;
+       crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end;
+       crt_reg.ver_sync_start =
+           (panel_crt_reg.ver_sync_start -
+            panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start;
+       crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end;
+
+       return crt_reg;
+}
+
+static void load_crtc_shadow_timing(struct display_timing mode_timing,
+                            struct display_timing panel_timing)
+{
+       struct io_register *reg = NULL;
+       int i;
+       int viafb_load_reg_Num = 0;
+       int reg_value = 0;
+
+       if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) {
+               /* Expansion */
+               for (i = 12; i < 20; i++) {
+                       switch (i) {
+                       case H_TOTAL_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_HOR_TOTAL_SHADOW_FORMULA
+                                   (panel_timing.hor_total);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.hor_total_shadow.
+                                   reg_num;
+                               reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
+                               break;
+                       case H_BLANK_END_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_HOR_BLANK_END_SHADOW_FORMULA
+                                   (panel_timing.hor_blank_start,
+                                    panel_timing.hor_blank_end);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   hor_blank_end_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   hor_blank_end_shadow.reg;
+                               break;
+                       case V_TOTAL_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_TOTAL_SHADOW_FORMULA
+                                   (panel_timing.ver_total);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.ver_total_shadow.
+                                   reg_num;
+                               reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
+                               break;
+                       case V_ADDR_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_ADDR_SHADOW_FORMULA
+                                   (panel_timing.ver_addr);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.ver_addr_shadow.
+                                   reg_num;
+                               reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
+                               break;
+                       case V_BLANK_SATRT_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_BLANK_START_SHADOW_FORMULA
+                                   (panel_timing.ver_blank_start);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_start_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_start_shadow.reg;
+                               break;
+                       case V_BLANK_END_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_BLANK_END_SHADOW_FORMULA
+                                   (panel_timing.ver_blank_start,
+                                    panel_timing.ver_blank_end);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_end_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_end_shadow.reg;
+                               break;
+                       case V_SYNC_SATRT_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_SYNC_START_SHADOW_FORMULA
+                                   (panel_timing.ver_sync_start);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   ver_sync_start_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   ver_sync_start_shadow.reg;
+                               break;
+                       case V_SYNC_END_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_SYNC_END_SHADOW_FORMULA
+                                   (panel_timing.ver_sync_start,
+                                    panel_timing.ver_sync_end);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   ver_sync_end_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   ver_sync_end_shadow.reg;
+                               break;
+                       }
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_Num, reg, VIACR);
+               }
+       } else {                /* Centering */
+               for (i = 12; i < 20; i++) {
+                       switch (i) {
+                       case H_TOTAL_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_HOR_TOTAL_SHADOW_FORMULA
+                                   (panel_timing.hor_total);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.hor_total_shadow.
+                                   reg_num;
+                               reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
+                               break;
+                       case H_BLANK_END_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_HOR_BLANK_END_SHADOW_FORMULA
+                                   (panel_timing.hor_blank_start,
+                                    panel_timing.hor_blank_end);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   hor_blank_end_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   hor_blank_end_shadow.reg;
+                               break;
+                       case V_TOTAL_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_TOTAL_SHADOW_FORMULA
+                                   (panel_timing.ver_total);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.ver_total_shadow.
+                                   reg_num;
+                               reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
+                               break;
+                       case V_ADDR_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_ADDR_SHADOW_FORMULA
+                                   (mode_timing.ver_addr);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.ver_addr_shadow.
+                                   reg_num;
+                               reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
+                               break;
+                       case V_BLANK_SATRT_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_BLANK_START_SHADOW_FORMULA
+                                   (mode_timing.ver_blank_start);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_start_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_start_shadow.reg;
+                               break;
+                       case V_BLANK_END_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_BLANK_END_SHADOW_FORMULA
+                                   (panel_timing.ver_blank_start,
+                                    panel_timing.ver_blank_end);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_end_shadow.reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.
+                                   ver_blank_end_shadow.reg;
+                               break;
+                       case V_SYNC_SATRT_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_SYNC_START_SHADOW_FORMULA(
+                                   (panel_timing.ver_sync_start -
+                                   panel_timing.ver_blank_start) +
+                                   (panel_timing.ver_addr -
+                                   mode_timing.ver_addr) / 2 +
+                                   mode_timing.ver_addr);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.ver_sync_start_shadow.
+                                   reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.ver_sync_start_shadow.
+                                   reg;
+                               break;
+                       case V_SYNC_END_SHADOW_INDEX:
+                               reg_value =
+                                   IGA2_VER_SYNC_END_SHADOW_FORMULA(
+                                   (panel_timing.ver_sync_start -
+                                   panel_timing.ver_blank_start) +
+                                   (panel_timing.ver_addr -
+                                   mode_timing.ver_addr) / 2 +
+                                   mode_timing.ver_addr,
+                                   panel_timing.ver_sync_end);
+                               viafb_load_reg_Num =
+                                   iga2_shadow_crtc_reg.ver_sync_end_shadow.
+                                   reg_num;
+                               reg =
+                                   iga2_shadow_crtc_reg.ver_sync_end_shadow.
+                                   reg;
+                               break;
+                       }
+                       viafb_load_reg(reg_value,
+                               viafb_load_reg_Num, reg, VIACR);
+               }
+       }
+}
+
+bool viafb_lcd_get_mobile_state(bool *mobile)
+{
+       unsigned char *romptr, *tableptr;
+       u8 core_base;
+       unsigned char *biosptr;
+       /* Rom address */
+       u32 romaddr = 0x000C0000;
+       u16 start_pattern = 0;
+
+       biosptr = ioremap(romaddr, 0x10000);
+
+       memcpy(&start_pattern, biosptr, 2);
+       /* Compare pattern */
+       if (start_pattern == 0xAA55) {
+               /* Get the start of Table */
+               /* 0x1B means BIOS offset position */
+               romptr = biosptr + 0x1B;
+               tableptr = biosptr + *((u16 *) romptr);
+
+               /* Get the start of biosver structure */
+               /* 18 means BIOS version position. */
+               romptr = tableptr + 18;
+               romptr = biosptr + *((u16 *) romptr);
+
+               /* The offset should be 44, but the
+                  actual image is less three char. */
+               /* pRom += 44; */
+               romptr += 41;
+
+               core_base = *romptr++;
+
+               if (core_base & 0x8)
+                       *mobile = false;
+               else
+                       *mobile = true;
+               /* release memory */
+               iounmap(biosptr);
+
+               return true;
+       } else {
+               iounmap(biosptr);
+               return false;
+       }
+}
+
+static void viafb_load_scaling_factor_for_p4m900(int set_hres,
+       int set_vres, int panel_hres, int panel_vres)
+{
+       int h_scaling_factor;
+       int v_scaling_factor;
+       u8 cra2 = 0;
+       u8 cr77 = 0;
+       u8 cr78 = 0;
+       u8 cr79 = 0;
+       u8 cr9f = 0;
+       /* Check if expansion for horizontal */
+       if (set_hres < panel_hres) {
+               /* Load Horizontal Scaling Factor */
+
+               /* For VIA_K8M800 or later chipsets. */
+               h_scaling_factor =
+                   K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
+               /* HSCaleFactor[1:0] at CR9F[1:0] */
+               cr9f = h_scaling_factor & 0x0003;
+               /* HSCaleFactor[9:2] at CR77[7:0] */
+               cr77 = (h_scaling_factor & 0x03FC) >> 2;
+               /* HSCaleFactor[11:10] at CR79[5:4] */
+               cr79 = (h_scaling_factor & 0x0C00) >> 10;
+               cr79 <<= 4;
+
+               /* Horizontal scaling enabled */
+               cra2 = 0xC0;
+
+               DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
+                         h_scaling_factor);
+       } else {
+               /* Horizontal scaling disabled */
+               cra2 = 0x00;
+       }
+
+       /* Check if expansion for vertical */
+       if (set_vres < panel_vres) {
+               /* Load Vertical Scaling Factor */
+
+               /* For VIA_K8M800 or later chipsets. */
+               v_scaling_factor =
+                   K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
+
+               /* Vertical scaling enabled */
+               cra2 |= 0x08;
+               /* VSCaleFactor[0] at CR79[3] */
+               cr79 |= ((v_scaling_factor & 0x0001) << 3);
+               /* VSCaleFactor[8:1] at CR78[7:0] */
+               cr78 |= (v_scaling_factor & 0x01FE) >> 1;
+               /* VSCaleFactor[10:9] at CR79[7:6] */
+               cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
+
+               DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
+                         v_scaling_factor);
+       } else {
+               /* Vertical scaling disabled */
+               cra2 |= 0x00;
+       }
+
+       viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
+       viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
+       viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
+       viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
+       viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
+}
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
new file mode 100644 (file)
index 0000000..071f47c
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __LCD_H__
+#define __LCD_H__
+
+/*Definition TMDS Device ID register*/
+#define     VT1631_DEVICE_ID_REG        0x02
+#define     VT1631_DEVICE_ID            0x92
+
+#define     VT3271_DEVICE_ID_REG        0x02
+#define     VT3271_DEVICE_ID            0x71
+
+#define     GET_LCD_SIZE_BY_SYSTEM_BIOS     0x01
+#define     GET_LCD_SIZE_BY_VGA_BIOS        0x02
+#define     GET_LCD_SZIE_BY_HW_STRAPPING    0x03
+#define     GET_LCD_SIZE_BY_USER_SETTING    0x04
+
+/* Definition DVI Panel ID*/
+/* Resolution: 640x480,   Channel: single, Dithering: Enable */
+#define     LCD_PANEL_ID0_640X480       0x00
+/* Resolution: 800x600,   Channel: single, Dithering: Enable */
+#define     LCD_PANEL_ID1_800X600       0x01
+/* Resolution: 1024x768,  Channel: single, Dithering: Enable */
+#define     LCD_PANEL_ID2_1024X768      0x02
+/* Resolution: 1280x768,  Channel: single, Dithering: Enable */
+#define     LCD_PANEL_ID3_1280X768      0x03
+/* Resolution: 1280x1024, Channel: dual,   Dithering: Enable */
+#define     LCD_PANEL_ID4_1280X1024     0x04
+/* Resolution: 1400x1050, Channel: dual,   Dithering: Enable */
+#define     LCD_PANEL_ID5_1400X1050     0x05
+/* Resolution: 1600x1200, Channel: dual,   Dithering: Enable */
+#define     LCD_PANEL_ID6_1600X1200     0x06
+/* Resolution: 1366x768,  Channel: single, Dithering: Disable */
+#define     LCD_PANEL_ID7_1366X768      0x07
+/* Resolution: 1024x600,  Channel: single, Dithering: Enable*/
+#define     LCD_PANEL_ID8_1024X600      0x08
+/* Resolution: 1280x800,  Channel: single, Dithering: Enable*/
+#define     LCD_PANEL_ID9_1280X800      0x09
+/* Resolution: 800x480,   Channel: single, Dithering: Enable*/
+#define     LCD_PANEL_IDA_800X480       0x0A
+/* Resolution: 1360x768,   Channel: single, Dithering: Disable*/
+#define     LCD_PANEL_IDB_1360X768     0x0B
+/* Resolution: 480x640,  Channel: single, Dithering: Enable */
+#define     LCD_PANEL_IDC_480X640      0x0C
+
+
+extern int viafb_LCD2_ON;
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+
+void viafb_disable_lvds_vt1636(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info);
+void viafb_enable_lvds_vt1636(struct lvds_setting_information
+                       *plvds_setting_info,
+                       struct lvds_chip_information *plvds_chip_info);
+void viafb_lcd_disable(void);
+void viafb_lcd_enable(void);
+void viafb_init_lcd_size(void);
+void viafb_init_lvds_output_interface(struct lvds_chip_information
+                               *plvds_chip_info,
+                               struct lvds_setting_information
+                               *plvds_setting_info);
+void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
+                 struct lvds_setting_information *plvds_setting_info,
+                 struct lvds_chip_information *plvds_chip_info);
+int viafb_lvds_trasmitter_identify(void);
+void viafb_init_lvds_output_interface(struct lvds_chip_information
+                               *plvds_chip_info,
+                               struct lvds_setting_information
+                               *plvds_setting_info);
+bool viafb_lcd_get_mobile_state(bool *mobile);
+void viafb_load_crtc_timing(struct display_timing device_timing,
+       int set_iga);
+
+#endif /* __LCD_H__ */
diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h
new file mode 100644 (file)
index 0000000..6f3dd80
--- /dev/null
@@ -0,0 +1,591 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __LCDTBL_H__
+#define __LCDTBL_H__
+
+#include "share.h"
+
+/* CLE266 Software Power Sequence */
+/* {Mask}, {Data}, {Delay} */
+int PowerSequenceOn[3][3] =
+    { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} };
+int PowerSequenceOff[3][3] =
+    { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} };
+
+/* ++++++ P880 ++++++ */
+/*   Panel 1600x1200   */
+struct io_reg P880_LCD_RES_6X4_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x5E},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C},
+       {VIASR, SR46, 0xFF, 0x02}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12)
+
+struct io_reg P880_LCD_RES_7X4_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x78},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C},
+       {VIASR, SR46, 0xFF, 0x01}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12)
+
+struct io_reg P880_LCD_RES_8X6_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x83},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88},
+       {VIASR, SR46, 0xFF, 0x03}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12)
+
+struct io_reg P880_LCD_RES_10X7_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xAF},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88},
+       {VIASR, SR46, 0xFF, 0x03}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12)
+
+struct io_reg P880_LCD_RES_12X10_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xD4},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88},
+       {VIASR, SR46, 0xFF, 0x05}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12)
+
+/*   Panel 1400x1050   */
+struct io_reg P880_LCD_RES_6X4_14X10[] = {
+       /* 640x480                          */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x63},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C},
+       {VIASR, SR46, 0xFF, 0x05}
+};
+
+#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10)
+
+struct io_reg P880_LCD_RES_8X6_14X10[] = {
+       /* 800x600                          */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x83},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D},
+       {VIASR, SR46, 0xFF, 0x05}
+};
+
+#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10)
+
+/* ++++++ K400 ++++++ */
+/*   Panel 1600x1200   */
+struct io_reg K400_LCD_RES_6X4_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x5E},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12)
+
+struct io_reg K400_LCD_RES_7X4_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x78},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12)
+
+struct io_reg K400_LCD_RES_8X6_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x83},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12)
+
+struct io_reg K400_LCD_RES_10X7_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xAF},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12)
+
+struct io_reg K400_LCD_RES_12X10_16X12[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
+       {VIACR, CR5D, 0x40, 0x40},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xD4},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12)
+
+/*   Panel 1400x1050   */
+struct io_reg K400_LCD_RES_6X4_14X10[] = {
+       /* 640x400                          */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x63},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10)
+
+struct io_reg K400_LCD_RES_8X6_14X10[] = {
+       /* 800x600                          */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x83},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10)
+
+struct io_reg K400_LCD_RES_10X7_14X10[] = {
+       /* 1024x768                         */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xA7},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10)
+
+struct io_reg K400_LCD_RES_12X10_14X10[] = {
+       /* 1280x768, 1280x960, 1280x1024    */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xD2},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10)
+
+/* ++++++ K400 ++++++ */
+/*   Panel 1366x768   */
+struct io_reg K400_LCD_RES_6X4_1366X7[] = {
+       /* 640x400                          */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
+       {VIACR, CR5D, 0x40, 0x13},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x64},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7)
+
+struct io_reg K400_LCD_RES_7X4_1366X7[] = {
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
+       {VIACR, CR5D, 0x40, 0x13},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x75},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7)
+
+struct io_reg K400_LCD_RES_8X6_1366X7[] = {
+       /* 800x600                          */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
+       {VIACR, CR5D, 0x40, 0x13},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x82},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7)
+
+struct io_reg K400_LCD_RES_10X7_1366X7[] = {
+       /* 1024x768                         */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xA7},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7)
+
+struct io_reg K400_LCD_RES_12X10_1366X7[] = {
+       /* 1280x768, 1280x960, 1280x1024    */
+       /* IGA2 Horizontal Total            */
+       {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
+       /* IGA2 Horizontal Blank End        */
+       {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
+       {VIACR, CR5D, 0x40, 0x24},
+       /* IGA2 Horizontal Total Shadow     */
+       {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
+       /* IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xD2},
+       /* IGA2 Offset                      */
+       {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
+       /* VCLK                             */
+       {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\
+                       ARRAY_SIZE(K400_LCD_RES_12X10_1366X7)
+
+/* ++++++ K400 ++++++ */
+/*   Panel 1280x1024   */
+struct io_reg K400_LCD_RES_6X4_12X10[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+       {VIACR, CR5D, 0x40, 0x1C},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x63},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10)
+
+struct io_reg K400_LCD_RES_7X4_12X10[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+       {VIACR, CR5D, 0x40, 0x1C},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x6C},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10)
+
+struct io_reg K400_LCD_RES_8X6_12X10[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+       {VIACR, CR5D, 0x40, 0x1C},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x83},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10)
+
+struct io_reg K400_LCD_RES_10X7_12X10[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+       {VIACR, CR5D, 0x40, 0x1C},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0xA7},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10)
+
+/* ++++++ K400 ++++++ */
+/*   Panel 1024x768    */
+struct io_reg K400_LCD_RES_6X4_10X7[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
+       {VIACR, CR5D, 0x40, 0x13},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x64},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7)
+
+struct io_reg K400_LCD_RES_7X4_10X7[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
+       {VIACR, CR5D, 0x40, 0x13},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x75},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7)
+
+struct io_reg K400_LCD_RES_8X6_10X7[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
+       {VIACR, CR5D, 0x40, 0x13},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x82},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7)
+
+/* ++++++ K400 ++++++ */
+/*   Panel 800x600     */
+struct io_reg K400_LCD_RES_6X4_8X6[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3},
+       {VIACR, CR5D, 0x40, 0x12},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x63},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6)
+
+struct io_reg K400_LCD_RES_7X4_8X6[] = {
+       /*IGA2 Horizontal Total */
+       {VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34},
+       /*IGA2 Horizontal Blank End */
+       {VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3},
+       {VIACR, CR5D, 0x40, 0x12},
+       /*IGA2 Horizontal Total Shadow */
+       {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22},
+       /*IGA2 Horizontal Blank End Shadow */
+       {VIACR, CR6E, 0xFF, 0x83},
+       /*IGA2 Offset */
+       {VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00},
+        /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6)
+
+#endif /* __LCDTBL_H__ */
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
new file mode 100644 (file)
index 0000000..2e1254d
--- /dev/null
@@ -0,0 +1,1105 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SHARE_H__
+#define __SHARE_H__
+
+/* Define Return Value */
+#define FAIL        -1
+#define OK          1
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Define Bit Field */
+#define BIT0    0x01
+#define BIT1    0x02
+#define BIT2    0x04
+#define BIT3    0x08
+#define BIT4    0x10
+#define BIT5    0x20
+#define BIT6    0x40
+#define BIT7    0x80
+
+/* Video Memory Size */
+#define VIDEO_MEMORY_SIZE_16M    0x1000000
+
+/* Definition Mode Index
+*/
+#define     VIA_RES_640X480                    0
+#define     VIA_RES_800X600                    1
+#define     VIA_RES_1024X768                   2
+#define     VIA_RES_1152X864                   3
+#define     VIA_RES_1280X1024                  4
+#define     VIA_RES_1600X1200                  5
+#define     VIA_RES_1440X1050                  6
+#define     VIA_RES_1280X768                   7
+#define     VIA_RES_1280X960                   8
+#define     VIA_RES_1920X1440                  9
+#define     VIA_RES_848X480                    10
+#define     VIA_RES_1400X1050                  11
+#define     VIA_RES_720X480                    12
+#define     VIA_RES_720X576                    13
+#define     VIA_RES_1024X512                   14
+#define     VIA_RES_856X480                    15
+#define     VIA_RES_1024X576                   16
+#define     VIA_RES_640X400                    17
+#define     VIA_RES_1280X720                   18
+#define     VIA_RES_1920X1080                  19
+#define     VIA_RES_800X480                    20
+#define     VIA_RES_1368X768                   21
+#define     VIA_RES_1024X600                   22
+#define     VIA_RES_1280X800                   23
+#define     VIA_RES_1680X1050                  24
+#define     VIA_RES_960X600                    25
+#define     VIA_RES_1000X600                   26
+#define     VIA_RES_1088X612                   27
+#define     VIA_RES_1152X720                   28
+#define     VIA_RES_1200X720                   29
+#define     VIA_RES_1280X600                   30
+#define     VIA_RES_1360X768                   31
+#define     VIA_RES_1366X768                   32
+#define     VIA_RES_1440X900                   33
+#define     VIA_RES_1600X900                   34
+#define     VIA_RES_1600X1024                  35
+#define     VIA_RES_1792X1344                  36
+#define     VIA_RES_1856X1392                  37
+#define     VIA_RES_1920X1200                  38
+#define     VIA_RES_2048X1536                  39
+#define     VIA_RES_480X640                    40
+
+/*Reduce Blanking*/
+#define     VIA_RES_1360X768_RB                131
+#define     VIA_RES_1440X900_RB                133
+#define     VIA_RES_1400X1050_RB               111
+#define     VIA_RES_1600X900_RB                134
+#define     VIA_RES_1680X1050_RB               124
+#define     VIA_RES_1920X1080_RB               119
+#define     VIA_RES_1920X1200_RB               138
+
+#define     VIA_RES_INVALID                    255
+
+/* standard VGA IO port
+*/
+#define VIARMisc    0x3CC
+#define VIAWMisc    0x3C2
+#define VIAStatus   0x3DA
+#define VIACR       0x3D4
+#define VIASR       0x3C4
+#define VIAGR       0x3CE
+#define VIAAR       0x3C0
+
+#define StdCR       0x19
+#define StdSR       0x04
+#define StdGR       0x09
+#define StdAR       0x14
+
+#define PatchCR     11
+
+/* Display path */
+#define IGA1        1
+#define IGA2        2
+#define IGA1_IGA2   3
+
+/* Define Color Depth  */
+#define MODE_8BPP       1
+#define MODE_16BPP      2
+#define MODE_32BPP      4
+
+#define GR20    0x20
+#define GR21    0x21
+#define GR22    0x22
+
+/* Sequencer Registers */
+#define SR01    0x01
+#define SR10    0x10
+#define SR12    0x12
+#define SR15    0x15
+#define SR16    0x16
+#define SR17    0x17
+#define SR18    0x18
+#define SR1B    0x1B
+#define SR1A    0x1A
+#define SR1C    0x1C
+#define SR1D    0x1D
+#define SR1E    0x1E
+#define SR1F    0x1F
+#define SR20    0x20
+#define SR21    0x21
+#define SR22    0x22
+#define SR2A    0x2A
+#define SR2D    0x2D
+#define SR2E    0x2E
+
+#define SR30    0x30
+#define SR39    0x39
+#define SR3D    0x3D
+#define SR3E    0x3E
+#define SR3F    0x3F
+#define SR40    0x40
+#define SR43    0x43
+#define SR44    0x44
+#define SR45    0x45
+#define SR46    0x46
+#define SR47    0x47
+#define SR48    0x48
+#define SR49    0x49
+#define SR4A    0x4A
+#define SR4B    0x4B
+#define SR4C    0x4C
+#define SR52    0x52
+#define SR5E    0x5E
+#define SR65    0x65
+
+/* CRT Controller Registers */
+#define CR00    0x00
+#define CR01    0x01
+#define CR02    0x02
+#define CR03    0x03
+#define CR04    0x04
+#define CR05    0x05
+#define CR06    0x06
+#define CR07    0x07
+#define CR08    0x08
+#define CR09    0x09
+#define CR0A    0x0A
+#define CR0B    0x0B
+#define CR0C    0x0C
+#define CR0D    0x0D
+#define CR0E    0x0E
+#define CR0F    0x0F
+#define CR10    0x10
+#define CR11    0x11
+#define CR12    0x12
+#define CR13    0x13
+#define CR14    0x14
+#define CR15    0x15
+#define CR16    0x16
+#define CR17    0x17
+#define CR18    0x18
+
+/* Extend CRT Controller Registers */
+#define CR30    0x30
+#define CR31    0x31
+#define CR32    0x32
+#define CR33    0x33
+#define CR34    0x34
+#define CR35    0x35
+#define CR36    0x36
+#define CR37    0x37
+#define CR38    0x38
+#define CR39    0x39
+#define CR3A    0x3A
+#define CR3B    0x3B
+#define CR3C    0x3C
+#define CR3D    0x3D
+#define CR3E    0x3E
+#define CR3F    0x3F
+#define CR40    0x40
+#define CR41    0x41
+#define CR42    0x42
+#define CR43    0x43
+#define CR44    0x44
+#define CR45    0x45
+#define CR46    0x46
+#define CR47    0x47
+#define CR48    0x48
+#define CR49    0x49
+#define CR4A    0x4A
+#define CR4B    0x4B
+#define CR4C    0x4C
+#define CR4D    0x4D
+#define CR4E    0x4E
+#define CR4F    0x4F
+#define CR50    0x50
+#define CR51    0x51
+#define CR52    0x52
+#define CR53    0x53
+#define CR54    0x54
+#define CR55    0x55
+#define CR56    0x56
+#define CR57    0x57
+#define CR58    0x58
+#define CR59    0x59
+#define CR5A    0x5A
+#define CR5B    0x5B
+#define CR5C    0x5C
+#define CR5D    0x5D
+#define CR5E    0x5E
+#define CR5F    0x5F
+#define CR60    0x60
+#define CR61    0x61
+#define CR62    0x62
+#define CR63    0x63
+#define CR64    0x64
+#define CR65    0x65
+#define CR66    0x66
+#define CR67    0x67
+#define CR68    0x68
+#define CR69    0x69
+#define CR6A    0x6A
+#define CR6B    0x6B
+#define CR6C    0x6C
+#define CR6D    0x6D
+#define CR6E    0x6E
+#define CR6F    0x6F
+#define CR70    0x70
+#define CR71    0x71
+#define CR72    0x72
+#define CR73    0x73
+#define CR74    0x74
+#define CR75    0x75
+#define CR76    0x76
+#define CR77    0x77
+#define CR78    0x78
+#define CR79    0x79
+#define CR7A    0x7A
+#define CR7B    0x7B
+#define CR7C    0x7C
+#define CR7D    0x7D
+#define CR7E    0x7E
+#define CR7F    0x7F
+#define CR80    0x80
+#define CR81    0x81
+#define CR82    0x82
+#define CR83    0x83
+#define CR84    0x84
+#define CR85    0x85
+#define CR86    0x86
+#define CR87    0x87
+#define CR88    0x88
+#define CR89    0x89
+#define CR8A    0x8A
+#define CR8B    0x8B
+#define CR8C    0x8C
+#define CR8D    0x8D
+#define CR8E    0x8E
+#define CR8F    0x8F
+#define CR90    0x90
+#define CR91    0x91
+#define CR92    0x92
+#define CR93    0x93
+#define CR94    0x94
+#define CR95    0x95
+#define CR96    0x96
+#define CR97    0x97
+#define CR98    0x98
+#define CR99    0x99
+#define CR9A    0x9A
+#define CR9B    0x9B
+#define CR9C    0x9C
+#define CR9D    0x9D
+#define CR9E    0x9E
+#define CR9F    0x9F
+#define CRA0    0xA0
+#define CRA1    0xA1
+#define CRA2    0xA2
+#define CRA3    0xA3
+#define CRD2    0xD2
+#define CRD3    0xD3
+#define CRD4    0xD4
+
+/* LUT Table*/
+#define LUT_DATA             0x3C9     /* DACDATA */
+#define LUT_INDEX_READ       0x3C7     /* DACRX */
+#define LUT_INDEX_WRITE      0x3C8     /* DACWX */
+#define DACMASK              0x3C6
+
+/* Definition Device */
+#define DEVICE_CRT  0x01
+#define DEVICE_DVI  0x03
+#define DEVICE_LCD  0x04
+
+/* Device output interface */
+#define INTERFACE_NONE          0x00
+#define INTERFACE_ANALOG_RGB    0x01
+#define INTERFACE_DVP0          0x02
+#define INTERFACE_DVP1          0x03
+#define INTERFACE_DFP_HIGH      0x04
+#define INTERFACE_DFP_LOW       0x05
+#define INTERFACE_DFP           0x06
+#define INTERFACE_LVDS0         0x07
+#define INTERFACE_LVDS1         0x08
+#define INTERFACE_LVDS0LVDS1    0x09
+#define INTERFACE_TMDS          0x0A
+
+#define HW_LAYOUT_LCD_ONLY      0x01
+#define HW_LAYOUT_DVI_ONLY      0x02
+#define HW_LAYOUT_LCD_DVI       0x03
+#define HW_LAYOUT_LCD1_LCD2     0x04
+#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10
+
+/* Definition Refresh Rate */
+#define REFRESH_50      50
+#define REFRESH_60      60
+#define REFRESH_75      75
+#define REFRESH_85      85
+#define REFRESH_100     100
+#define REFRESH_120     120
+
+/* Definition Sync Polarity*/
+#define NEGATIVE        1
+#define POSITIVE        0
+
+/*480x640@60 Sync Polarity (GTF)
+*/
+#define M480X640_R60_HSP        NEGATIVE
+#define M480X640_R60_VSP        POSITIVE
+
+/*640x480@60 Sync Polarity (VESA Mode)
+*/
+#define M640X480_R60_HSP        NEGATIVE
+#define M640X480_R60_VSP        NEGATIVE
+
+/*640x480@75 Sync Polarity (VESA Mode)
+*/
+#define M640X480_R75_HSP        NEGATIVE
+#define M640X480_R75_VSP        NEGATIVE
+
+/*640x480@85 Sync Polarity (VESA Mode)
+*/
+#define M640X480_R85_HSP        NEGATIVE
+#define M640X480_R85_VSP        NEGATIVE
+
+/*640x480@100 Sync Polarity (GTF Mode)
+*/
+#define M640X480_R100_HSP       NEGATIVE
+#define M640X480_R100_VSP       POSITIVE
+
+/*640x480@120 Sync Polarity (GTF Mode)
+*/
+#define M640X480_R120_HSP       NEGATIVE
+#define M640X480_R120_VSP       POSITIVE
+
+/*720x480@60 Sync Polarity  (GTF Mode)
+*/
+#define M720X480_R60_HSP        NEGATIVE
+#define M720X480_R60_VSP        POSITIVE
+
+/*720x576@60 Sync Polarity  (GTF Mode)
+*/
+#define M720X576_R60_HSP        NEGATIVE
+#define M720X576_R60_VSP        POSITIVE
+
+/*800x600@60 Sync Polarity (VESA Mode)
+*/
+#define M800X600_R60_HSP        POSITIVE
+#define M800X600_R60_VSP        POSITIVE
+
+/*800x600@75 Sync Polarity (VESA Mode)
+*/
+#define M800X600_R75_HSP        POSITIVE
+#define M800X600_R75_VSP        POSITIVE
+
+/*800x600@85 Sync Polarity (VESA Mode)
+*/
+#define M800X600_R85_HSP        POSITIVE
+#define M800X600_R85_VSP        POSITIVE
+
+/*800x600@100 Sync Polarity (GTF Mode)
+*/
+#define M800X600_R100_HSP       NEGATIVE
+#define M800X600_R100_VSP       POSITIVE
+
+/*800x600@120 Sync Polarity (GTF Mode)
+*/
+#define M800X600_R120_HSP       NEGATIVE
+#define M800X600_R120_VSP       POSITIVE
+
+/*800x480@60 Sync Polarity  (CVT Mode)
+*/
+#define M800X480_R60_HSP        NEGATIVE
+#define M800X480_R60_VSP        POSITIVE
+
+/*848x480@60 Sync Polarity  (CVT Mode)
+*/
+#define M848X480_R60_HSP        NEGATIVE
+#define M848X480_R60_VSP        POSITIVE
+
+/*852x480@60 Sync Polarity  (GTF Mode)
+*/
+#define M852X480_R60_HSP        NEGATIVE
+#define M852X480_R60_VSP        POSITIVE
+
+/*1024x512@60 Sync Polarity (GTF Mode)
+*/
+#define M1024X512_R60_HSP       NEGATIVE
+#define M1024X512_R60_VSP       POSITIVE
+
+/*1024x600@60 Sync Polarity (GTF Mode)
+*/
+#define M1024X600_R60_HSP       NEGATIVE
+#define M1024X600_R60_VSP       POSITIVE
+
+/*1024x768@60 Sync Polarity (VESA Mode)
+*/
+#define M1024X768_R60_HSP       NEGATIVE
+#define M1024X768_R60_VSP       NEGATIVE
+
+/*1024x768@75 Sync Polarity (VESA Mode)
+*/
+#define M1024X768_R75_HSP       POSITIVE
+#define M1024X768_R75_VSP       POSITIVE
+
+/*1024x768@85 Sync Polarity (VESA Mode)
+*/
+#define M1024X768_R85_HSP       POSITIVE
+#define M1024X768_R85_VSP       POSITIVE
+
+/*1024x768@100 Sync Polarity (GTF Mode)
+*/
+#define M1024X768_R100_HSP      NEGATIVE
+#define M1024X768_R100_VSP      POSITIVE
+
+/*1152x864@75 Sync Polarity (VESA Mode)
+*/
+#define M1152X864_R75_HSP       POSITIVE
+#define M1152X864_R75_VSP       POSITIVE
+
+/*1280x720@60 Sync Polarity  (GTF Mode)
+*/
+#define M1280X720_R60_HSP       NEGATIVE
+#define M1280X720_R60_VSP       POSITIVE
+
+/* 1280x768@50 Sync Polarity  (GTF Mode) */
+#define M1280X768_R50_HSP       NEGATIVE
+#define M1280X768_R50_VSP       POSITIVE
+
+/*1280x768@60 Sync Polarity  (GTF Mode)
+*/
+#define M1280X768_R60_HSP       NEGATIVE
+#define M1280X768_R60_VSP       POSITIVE
+
+/*1280x800@60 Sync Polarity  (CVT Mode)
+*/
+#define M1280X800_R60_HSP       NEGATIVE
+#define M1280X800_R60_VSP       POSITIVE
+
+/*1280x960@60 Sync Polarity (VESA Mode)
+*/
+#define M1280X960_R60_HSP       POSITIVE
+#define M1280X960_R60_VSP       POSITIVE
+
+/*1280x1024@60 Sync Polarity (VESA Mode)
+*/
+#define M1280X1024_R60_HSP      POSITIVE
+#define M1280X1024_R60_VSP      POSITIVE
+
+/* 1360x768@60 Sync Polarity (CVT Mode) */
+#define M1360X768_R60_HSP       POSITIVE
+#define M1360X768_R60_VSP       POSITIVE
+
+/* 1360x768@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1360X768_RB_R60_HSP       POSITIVE
+#define M1360X768_RB_R60_VSP       NEGATIVE
+
+/* 1368x768@50 Sync Polarity (GTF Mode) */
+#define M1368X768_R50_HSP       NEGATIVE
+#define M1368X768_R50_VSP       POSITIVE
+
+/* 1368x768@60 Sync Polarity (VESA Mode) */
+#define M1368X768_R60_HSP       NEGATIVE
+#define M1368X768_R60_VSP       POSITIVE
+
+/*1280x1024@75 Sync Polarity (VESA Mode)
+*/
+#define M1280X1024_R75_HSP      POSITIVE
+#define M1280X1024_R75_VSP      POSITIVE
+
+/*1280x1024@85 Sync Polarity (VESA Mode)
+*/
+#define M1280X1024_R85_HSP      POSITIVE
+#define M1280X1024_R85_VSP      POSITIVE
+
+/*1440x1050@60 Sync Polarity (GTF Mode)
+*/
+#define M1440X1050_R60_HSP      NEGATIVE
+#define M1440X1050_R60_VSP      POSITIVE
+
+/*1600x1200@60 Sync Polarity (VESA Mode)
+*/
+#define M1600X1200_R60_HSP      POSITIVE
+#define M1600X1200_R60_VSP      POSITIVE
+
+/*1600x1200@75 Sync Polarity (VESA Mode)
+*/
+#define M1600X1200_R75_HSP      POSITIVE
+#define M1600X1200_R75_VSP      POSITIVE
+
+/* 1680x1050@60 Sync Polarity (CVT Mode) */
+#define M1680x1050_R60_HSP      NEGATIVE
+#define M1680x1050_R60_VSP      NEGATIVE
+
+/* 1680x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1680x1050_RB_R60_HSP      POSITIVE
+#define M1680x1050_RB_R60_VSP      NEGATIVE
+
+/* 1680x1050@75 Sync Polarity (CVT Mode) */
+#define M1680x1050_R75_HSP      NEGATIVE
+#define M1680x1050_R75_VSP      POSITIVE
+
+/*1920x1080@60 Sync Polarity (CVT Mode)
+*/
+#define M1920X1080_R60_HSP      NEGATIVE
+#define M1920X1080_R60_VSP      POSITIVE
+
+/* 1920x1080@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1920X1080_RB_R60_HSP  POSITIVE
+#define M1920X1080_RB_R60_VSP  NEGATIVE
+
+/*1920x1440@60 Sync Polarity (VESA Mode)
+*/
+#define M1920X1440_R60_HSP      NEGATIVE
+#define M1920X1440_R60_VSP      POSITIVE
+
+/*1920x1440@75 Sync Polarity (VESA Mode)
+*/
+#define M1920X1440_R75_HSP      NEGATIVE
+#define M1920X1440_R75_VSP      POSITIVE
+
+#if 0
+/* 1400x1050@60 Sync Polarity (VESA Mode) */
+#define M1400X1050_R60_HSP      NEGATIVE
+#define M1400X1050_R60_VSP      NEGATIVE
+#endif
+
+/* 1400x1050@60 Sync Polarity (CVT Mode) */
+#define M1400X1050_R60_HSP      NEGATIVE
+#define M1400X1050_R60_VSP      POSITIVE
+
+/* 1400x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1400X1050_RB_R60_HSP      POSITIVE
+#define M1400X1050_RB_R60_VSP      NEGATIVE
+
+/* 1400x1050@75 Sync Polarity (CVT Mode) */
+#define M1400X1050_R75_HSP      NEGATIVE
+#define M1400X1050_R75_VSP      POSITIVE
+
+/* 960x600@60 Sync Polarity (CVT Mode) */
+#define M960X600_R60_HSP        NEGATIVE
+#define M960X600_R60_VSP        POSITIVE
+
+/* 1000x600@60 Sync Polarity (GTF Mode) */
+#define M1000X600_R60_HSP       NEGATIVE
+#define M1000X600_R60_VSP       POSITIVE
+
+/* 1024x576@60 Sync Polarity (GTF Mode) */
+#define M1024X576_R60_HSP       NEGATIVE
+#define M1024X576_R60_VSP       POSITIVE
+
+/*1024x600@60 Sync Polarity (GTF Mode)*/
+#define M1024X600_R60_HSP       NEGATIVE
+#define M1024X600_R60_VSP       POSITIVE
+
+/* 1088x612@60 Sync Polarity (CVT Mode) */
+#define M1088X612_R60_HSP       NEGATIVE
+#define M1088X612_R60_VSP       POSITIVE
+
+/* 1152x720@60 Sync Polarity (CVT Mode) */
+#define M1152X720_R60_HSP       NEGATIVE
+#define M1152X720_R60_VSP       POSITIVE
+
+/* 1200x720@60 Sync Polarity (GTF Mode) */
+#define M1200X720_R60_HSP       NEGATIVE
+#define M1200X720_R60_VSP       POSITIVE
+
+/* 1280x600@60 Sync Polarity (GTF Mode) */
+#define M1280x600_R60_HSP       NEGATIVE
+#define M1280x600_R60_VSP       POSITIVE
+
+/* 1280x720@50 Sync Polarity  (GTF Mode) */
+#define M1280X720_R50_HSP       NEGATIVE
+#define M1280X720_R50_VSP       POSITIVE
+
+/* 1280x720@60 Sync Polarity  (CEA Mode) */
+#define M1280X720_CEA_R60_HSP       POSITIVE
+#define M1280X720_CEA_R60_VSP       POSITIVE
+
+/* 1440x900@60 Sync Polarity (CVT Mode) */
+#define M1440X900_R60_HSP       NEGATIVE
+#define M1440X900_R60_VSP       POSITIVE
+
+/* 1440x900@75 Sync Polarity (CVT Mode) */
+#define M1440X900_R75_HSP       NEGATIVE
+#define M1440X900_R75_VSP       POSITIVE
+
+/* 1440x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1440X900_RB_R60_HSP       POSITIVE
+#define M1440X900_RB_R60_VSP       NEGATIVE
+
+/* 1600x900@60 Sync Polarity (CVT Mode) */
+#define M1600X900_R60_HSP       NEGATIVE
+#define M1600X900_R60_VSP       POSITIVE
+
+/* 1600x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1600X900_RB_R60_HSP       POSITIVE
+#define M1600X900_RB_R60_VSP       NEGATIVE
+
+/* 1600x1024@60 Sync Polarity (GTF Mode) */
+#define M1600X1024_R60_HSP      NEGATIVE
+#define M1600X1024_R60_VSP      POSITIVE
+
+/* 1792x1344@60 Sync Polarity (DMT Mode) */
+#define M1792x1344_R60_HSP      NEGATIVE
+#define M1792x1344_R60_VSP      POSITIVE
+
+/* 1856x1392@60 Sync Polarity (DMT Mode) */
+#define M1856x1392_R60_HSP      NEGATIVE
+#define M1856x1392_R60_VSP      POSITIVE
+
+/* 1920x1200@60 Sync Polarity (CVT Mode) */
+#define M1920X1200_R60_HSP      NEGATIVE
+#define M1920X1200_R60_VSP      POSITIVE
+
+/* 1920x1200@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1920X1200_RB_R60_HSP  POSITIVE
+#define M1920X1200_RB_R60_VSP  NEGATIVE
+
+/* 1920x1080@60 Sync Polarity  (CEA Mode) */
+#define M1920X1080_CEA_R60_HSP       POSITIVE
+#define M1920X1080_CEA_R60_VSP       POSITIVE
+
+/* 2048x1536@60 Sync Polarity (CVT Mode) */
+#define M2048x1536_R60_HSP      NEGATIVE
+#define M2048x1536_R60_VSP      POSITIVE
+
+/* define PLL index: */
+#define CLK_25_175M     25175000
+#define CLK_26_880M     26880000
+#define CLK_29_581M     29581000
+#define CLK_31_490M     31490000
+#define CLK_31_500M     31500000
+#define CLK_31_728M     31728000
+#define CLK_32_668M     32688000
+#define CLK_36_000M     36000000
+#define CLK_40_000M     40000000
+#define CLK_41_291M     41291000
+#define CLK_43_163M     43163000
+#define CLK_45_250M     45250000       /* 45.46MHz */
+#define CLK_46_000M     46000000
+#define CLK_46_996M     46996000
+#define CLK_48_000M     48000000
+#define CLK_48_875M     48875000
+#define CLK_49_500M     49500000
+#define CLK_52_406M     52406000
+#define CLK_52_977M     52977000
+#define CLK_56_250M     56250000
+#define CLK_60_466M     60466000
+#define CLK_61_500M     61500000
+#define CLK_65_000M     65000000
+#define CLK_65_178M     65178000
+#define CLK_66_750M     66750000       /* 67.116MHz */
+#define CLK_68_179M     68179000
+#define CLK_69_924M     69924000
+#define CLK_70_159M     70159000
+#define CLK_72_000M     72000000
+#define CLK_74_270M     74270000
+#define CLK_78_750M     78750000
+#define CLK_80_136M     80136000
+#define CLK_83_375M     83375000
+#define CLK_83_950M     83950000
+#define CLK_84_750M     84750000       /* 84.537Mhz */
+#define CLK_85_860M     85860000
+#define CLK_88_750M     88750000
+#define CLK_94_500M     94500000
+#define CLK_97_750M     97750000
+#define CLK_101_000M    101000000
+#define CLK_106_500M    106500000
+#define CLK_108_000M    108000000
+#define CLK_113_309M    113309000
+#define CLK_118_840M    118840000
+#define CLK_119_000M    119000000
+#define CLK_121_750M    121750000      /* 121.704MHz */
+#define CLK_125_104M    125104000
+#define CLK_133_308M    133308000
+#define CLK_135_000M    135000000
+#define CLK_136_700M    136700000
+#define CLK_138_400M    138400000
+#define CLK_146_760M    146760000
+#define CLK_148_500M    148500000
+
+#define CLK_153_920M    153920000
+#define CLK_156_000M    156000000
+#define CLK_157_500M    157500000
+#define CLK_162_000M    162000000
+#define CLK_187_000M    187000000
+#define CLK_193_295M    193295000
+#define CLK_202_500M    202500000
+#define CLK_204_000M    204000000
+#define CLK_218_500M    218500000
+#define CLK_234_000M    234000000
+#define CLK_267_250M    267250000
+#define CLK_297_500M    297500000
+#define CLK_74_481M     74481000
+#define CLK_172_798M    172798000
+#define CLK_122_614M    122614000
+
+/* CLE266 PLL value
+*/
+#define CLE266_PLL_25_175M     0x0000C763
+#define CLE266_PLL_26_880M     0x0000440F
+#define CLE266_PLL_29_581M     0x00008421
+#define CLE266_PLL_31_490M     0x00004721
+#define CLE266_PLL_31_500M     0x0000C3B5
+#define CLE266_PLL_31_728M     0x0000471F
+#define CLE266_PLL_32_668M     0x0000C449
+#define CLE266_PLL_36_000M     0x0000C5E5
+#define CLE266_PLL_40_000M     0x0000C459
+#define CLE266_PLL_41_291M     0x00004417
+#define CLE266_PLL_43_163M     0x0000C579
+#define CLE266_PLL_45_250M     0x0000C57F      /* 45.46MHz */
+#define CLE266_PLL_46_000M     0x0000875A
+#define CLE266_PLL_46_996M     0x0000C4E9
+#define CLE266_PLL_48_000M     0x00001443
+#define CLE266_PLL_48_875M     0x00001D63
+#define CLE266_PLL_49_500M     0x00008653
+#define CLE266_PLL_52_406M     0x0000C475
+#define CLE266_PLL_52_977M     0x00004525
+#define CLE266_PLL_56_250M     0x000047B7
+#define CLE266_PLL_60_466M     0x0000494C
+#define CLE266_PLL_61_500M     0x00001456
+#define CLE266_PLL_65_000M     0x000086ED
+#define CLE266_PLL_65_178M     0x0000855B
+#define CLE266_PLL_66_750M     0x0000844B      /* 67.116MHz */
+#define CLE266_PLL_68_179M     0x00000413
+#define CLE266_PLL_69_924M     0x00001153
+#define CLE266_PLL_70_159M     0x00001462
+#define CLE266_PLL_72_000M     0x00001879
+#define CLE266_PLL_74_270M     0x00004853
+#define CLE266_PLL_78_750M     0x00004321
+#define CLE266_PLL_80_136M     0x0000051C
+#define CLE266_PLL_83_375M     0x0000C25D
+#define CLE266_PLL_83_950M     0x00000729
+#define CLE266_PLL_84_750M     0x00008576      /* 84.537MHz */
+#define CLE266_PLL_85_860M     0x00004754
+#define CLE266_PLL_88_750M     0x0000051F
+#define CLE266_PLL_94_500M     0x00000521
+#define CLE266_PLL_97_750M     0x00004652
+#define CLE266_PLL_101_000M    0x0000497F
+#define CLE266_PLL_106_500M    0x00008477      /* 106.491463 MHz */
+#define CLE266_PLL_108_000M    0x00008479
+#define CLE266_PLL_113_309M    0x00000C5F
+#define CLE266_PLL_118_840M    0x00004553
+#define CLE266_PLL_119_000M    0x00000D6C
+#define CLE266_PLL_121_750M    0x00004555      /* 121.704MHz */
+#define CLE266_PLL_125_104M    0x000006B5
+#define CLE266_PLL_133_308M    0x0000465F
+#define CLE266_PLL_135_000M    0x0000455E
+#define CLE266_PLL_136_700M    0x00000C73
+#define CLE266_PLL_138_400M    0x00000957
+#define CLE266_PLL_146_760M    0x00004567
+#define CLE266_PLL_148_500M    0x00000853
+#define CLE266_PLL_153_920M    0x00000856
+#define CLE266_PLL_156_000M    0x0000456D
+#define CLE266_PLL_157_500M    0x000005B7
+#define CLE266_PLL_162_000M    0x00004571
+#define CLE266_PLL_187_000M    0x00000976
+#define CLE266_PLL_193_295M    0x0000086C
+#define CLE266_PLL_202_500M    0x00000763
+#define CLE266_PLL_204_000M    0x00000764
+#define CLE266_PLL_218_500M    0x0000065C
+#define CLE266_PLL_234_000M    0x00000662
+#define CLE266_PLL_267_250M    0x00000670
+#define CLE266_PLL_297_500M    0x000005E6
+#define CLE266_PLL_74_481M     0x0000051A
+#define CLE266_PLL_172_798M    0x00004579
+#define CLE266_PLL_122_614M    0x0000073C
+
+/* K800 PLL value
+*/
+#define K800_PLL_25_175M     0x00539001
+#define K800_PLL_26_880M     0x001C8C80
+#define K800_PLL_29_581M     0x00409080
+#define K800_PLL_31_490M     0x006F9001
+#define K800_PLL_31_500M     0x008B9002
+#define K800_PLL_31_728M     0x00AF9003
+#define K800_PLL_32_668M     0x00909002
+#define K800_PLL_36_000M     0x009F9002
+#define K800_PLL_40_000M     0x00578C02
+#define K800_PLL_41_291M     0x00438C01
+#define K800_PLL_43_163M     0x00778C03
+#define K800_PLL_45_250M     0x007D8C83        /* 45.46MHz */
+#define K800_PLL_46_000M     0x00658C02
+#define K800_PLL_46_996M     0x00818C83
+#define K800_PLL_48_000M     0x00848C83
+#define K800_PLL_48_875M     0x00508C81
+#define K800_PLL_49_500M     0x00518C01
+#define K800_PLL_52_406M     0x00738C02
+#define K800_PLL_52_977M     0x00928C83
+#define K800_PLL_56_250M     0x007C8C02
+#define K800_PLL_60_466M     0x00A78C83
+#define K800_PLL_61_500M     0x00AA8C83
+#define K800_PLL_65_000M     0x006B8C01
+#define K800_PLL_65_178M     0x00B48C83
+#define K800_PLL_66_750M     0x00948C82        /* 67.116MHz */
+#define K800_PLL_68_179M     0x00708C01
+#define K800_PLL_69_924M     0x00C18C83
+#define K800_PLL_70_159M     0x00C28C83
+#define K800_PLL_72_000M     0x009F8C82
+#define K800_PLL_74_270M     0x00ce0c03
+#define K800_PLL_78_750M     0x00408801
+#define K800_PLL_80_136M     0x00428801
+#define K800_PLL_83_375M     0x005B0882
+#define K800_PLL_83_950M     0x00738803
+#define K800_PLL_84_750M     0x00748883        /* 84.477MHz */
+#define K800_PLL_85_860M     0x00768883
+#define K800_PLL_88_750M     0x007A8883
+#define K800_PLL_94_500M     0x00828803
+#define K800_PLL_97_750M     0x00878883
+#define K800_PLL_101_000M    0x008B8883
+#define K800_PLL_106_500M    0x00758882        /* 106.491463 MHz */
+#define K800_PLL_108_000M    0x00778882
+#define K800_PLL_113_309M    0x005D8881
+#define K800_PLL_118_840M    0x00A48883
+#define K800_PLL_119_000M    0x00838882
+#define K800_PLL_121_750M    0x00A88883        /* 121.704MHz */
+#define K800_PLL_125_104M    0x00688801
+#define K800_PLL_133_308M    0x005D8801
+#define K800_PLL_135_000M    0x001A4081
+#define K800_PLL_136_700M    0x00BD8883
+#define K800_PLL_138_400M    0x00728881
+#define K800_PLL_146_760M    0x00CC8883
+#define K800_PLL_148_500M    0x00ce0803
+#define K800_PLL_153_920M    0x00548482
+#define K800_PLL_156_000M    0x006B8483
+#define K800_PLL_157_500M    0x00142080
+#define K800_PLL_162_000M    0x006F8483
+#define K800_PLL_187_000M    0x00818483
+#define K800_PLL_193_295M    0x004F8481
+#define K800_PLL_202_500M    0x00538481
+#define K800_PLL_204_000M    0x008D8483
+#define K800_PLL_218_500M    0x00978483
+#define K800_PLL_234_000M    0x00608401
+#define K800_PLL_267_250M    0x006E8481
+#define K800_PLL_297_500M    0x00A48402
+#define K800_PLL_74_481M     0x007B8C81
+#define K800_PLL_172_798M    0x00778483
+#define K800_PLL_122_614M    0x00878882
+
+/* PLL for VT3324 */
+#define CX700_25_175M     0x008B1003
+#define CX700_26_719M     0x00931003
+#define CX700_26_880M     0x00941003
+#define CX700_29_581M     0x00A49003
+#define CX700_31_490M     0x00AE1003
+#define CX700_31_500M     0x00AE1003
+#define CX700_31_728M     0x00AF1003
+#define CX700_32_668M     0x00B51003
+#define CX700_36_000M     0x00C81003
+#define CX700_40_000M     0x006E0C03
+#define CX700_41_291M     0x00710C03
+#define CX700_43_163M     0x00770C03
+#define CX700_45_250M     0x007D0C03   /* 45.46MHz */
+#define CX700_46_000M     0x007F0C03
+#define CX700_46_996M     0x00818C83
+#define CX700_48_000M     0x00840C03
+#define CX700_48_875M     0x00508C81
+#define CX700_49_500M     0x00880C03
+#define CX700_52_406M     0x00730C02
+#define CX700_52_977M     0x00920C03
+#define CX700_56_250M     0x009B0C03
+#define CX700_60_466M     0x00460C00
+#define CX700_61_500M     0x00AA0C03
+#define CX700_65_000M     0x006B0C01
+#define CX700_65_178M     0x006B0C01
+#define CX700_66_750M     0x00940C02   /*67.116MHz */
+#define CX700_68_179M     0x00BC0C03
+#define CX700_69_924M     0x00C10C03
+#define CX700_70_159M     0x00C20C03
+#define CX700_72_000M     0x009F0C02
+#define CX700_74_270M     0x00CE0C03
+#define CX700_74_481M     0x00CE0C03
+#define CX700_78_750M     0x006C0803
+#define CX700_80_136M     0x006E0803
+#define CX700_83_375M     0x005B0882
+#define CX700_83_950M     0x00730803
+#define CX700_84_750M     0x00740803   /* 84.537Mhz */
+#define CX700_85_860M     0x00760803
+#define CX700_88_750M     0x00AC8885
+#define CX700_94_500M     0x00820803
+#define CX700_97_750M     0x00870803
+#define CX700_101_000M    0x008B0803
+#define CX700_106_500M    0x00750802
+#define CX700_108_000M    0x00950803
+#define CX700_113_309M    0x005D0801
+#define CX700_118_840M    0x00A40803
+#define CX700_119_000M    0x00830802
+#define CX700_121_750M    0x00420800   /* 121.704MHz */
+#define CX700_125_104M    0x00AD0803
+#define CX700_133_308M    0x00930802
+#define CX700_135_000M    0x00950802
+#define CX700_136_700M    0x00BD0803
+#define CX700_138_400M    0x00720801
+#define CX700_146_760M    0x00CC0803
+#define CX700_148_500M    0x00a40802
+#define CX700_153_920M    0x00540402
+#define CX700_156_000M    0x006B0403
+#define CX700_157_500M    0x006C0403
+#define CX700_162_000M    0x006F0403
+#define CX700_172_798M    0x00770403
+#define CX700_187_000M    0x00810403
+#define CX700_193_295M    0x00850403
+#define CX700_202_500M    0x008C0403
+#define CX700_204_000M    0x008D0403
+#define CX700_218_500M    0x00970403
+#define CX700_234_000M    0x00600401
+#define CX700_267_250M    0x00B90403
+#define CX700_297_500M    0x00CE0403
+#define CX700_122_614M    0x00870802
+
+/* Definition CRTC Timing Index */
+#define H_TOTAL_INDEX               0
+#define H_ADDR_INDEX                1
+#define H_BLANK_START_INDEX         2
+#define H_BLANK_END_INDEX           3
+#define H_SYNC_START_INDEX          4
+#define H_SYNC_END_INDEX            5
+#define V_TOTAL_INDEX               6
+#define V_ADDR_INDEX                7
+#define V_BLANK_START_INDEX         8
+#define V_BLANK_END_INDEX           9
+#define V_SYNC_START_INDEX          10
+#define V_SYNC_END_INDEX            11
+#define H_TOTAL_SHADOW_INDEX        12
+#define H_BLANK_END_SHADOW_INDEX    13
+#define V_TOTAL_SHADOW_INDEX        14
+#define V_ADDR_SHADOW_INDEX         15
+#define V_BLANK_SATRT_SHADOW_INDEX  16
+#define V_BLANK_END_SHADOW_INDEX    17
+#define V_SYNC_SATRT_SHADOW_INDEX   18
+#define V_SYNC_END_SHADOW_INDEX     19
+
+/* Definition Video Mode Pixel Clock (picoseconds)
+*/
+#define RES_480X640_60HZ_PIXCLOCK    39722
+#define RES_640X480_60HZ_PIXCLOCK    39722
+#define RES_640X480_75HZ_PIXCLOCK    31747
+#define RES_640X480_85HZ_PIXCLOCK    27777
+#define RES_640X480_100HZ_PIXCLOCK   23168
+#define RES_640X480_120HZ_PIXCLOCK   19081
+#define RES_720X480_60HZ_PIXCLOCK    37020
+#define RES_720X576_60HZ_PIXCLOCK    30611
+#define RES_800X600_60HZ_PIXCLOCK    25000
+#define RES_800X600_75HZ_PIXCLOCK    20203
+#define RES_800X600_85HZ_PIXCLOCK    17777
+#define RES_800X600_100HZ_PIXCLOCK   14667
+#define RES_800X600_120HZ_PIXCLOCK   11912
+#define RES_800X480_60HZ_PIXCLOCK    33805
+#define RES_848X480_60HZ_PIXCLOCK    31756
+#define RES_856X480_60HZ_PIXCLOCK    31518
+#define RES_1024X512_60HZ_PIXCLOCK   24218
+#define RES_1024X600_60HZ_PIXCLOCK   20460
+#define RES_1024X768_60HZ_PIXCLOCK   15385
+#define RES_1024X768_75HZ_PIXCLOCK   12699
+#define RES_1024X768_85HZ_PIXCLOCK   10582
+#define RES_1024X768_100HZ_PIXCLOCK  8825
+#define RES_1152X864_75HZ_PIXCLOCK   9259
+#define RES_1280X768_60HZ_PIXCLOCK   12480
+#define RES_1280X800_60HZ_PIXCLOCK   11994
+#define RES_1280X960_60HZ_PIXCLOCK   9259
+#define RES_1280X1024_60HZ_PIXCLOCK  9260
+#define RES_1280X1024_75HZ_PIXCLOCK  7408
+#define RES_1280X768_85HZ_PIXCLOCK   6349
+#define RES_1440X1050_60HZ_PIXCLOCK  7993
+#define RES_1600X1200_60HZ_PIXCLOCK  6172
+#define RES_1600X1200_75HZ_PIXCLOCK  4938
+#define RES_1280X720_60HZ_PIXCLOCK   13426
+#define RES_1920X1080_60HZ_PIXCLOCK  5787
+#define RES_1400X1050_60HZ_PIXCLOCK  8214
+#define RES_1400X1050_75HZ_PIXCLOCK  6410
+#define RES_1368X768_60HZ_PIXCLOCK   11647
+#define RES_960X600_60HZ_PIXCLOCK      22099
+#define RES_1000X600_60HZ_PIXCLOCK    20834
+#define RES_1024X576_60HZ_PIXCLOCK    21278
+#define RES_1088X612_60HZ_PIXCLOCK    18877
+#define RES_1152X720_60HZ_PIXCLOCK    14981
+#define RES_1200X720_60HZ_PIXCLOCK    14253
+#define RES_1280X600_60HZ_PIXCLOCK    16260
+#define RES_1280X720_50HZ_PIXCLOCK    16538
+#define RES_1280X768_50HZ_PIXCLOCK    15342
+#define RES_1366X768_50HZ_PIXCLOCK    14301
+#define RES_1366X768_60HZ_PIXCLOCK    11646
+#define RES_1360X768_60HZ_PIXCLOCK    11799
+#define RES_1440X900_60HZ_PIXCLOCK    9390
+#define RES_1440X900_75HZ_PIXCLOCK    7315
+#define RES_1600X900_60HZ_PIXCLOCK    8415
+#define RES_1600X1024_60HZ_PIXCLOCK   7315
+#define RES_1680X1050_60HZ_PIXCLOCK   6814
+#define RES_1680X1050_75HZ_PIXCLOCK   5348
+#define RES_1792X1344_60HZ_PIXCLOCK   4902
+#define RES_1856X1392_60HZ_PIXCLOCK   4577
+#define RES_1920X1200_60HZ_PIXCLOCK   5173
+#define RES_1920X1440_60HZ_PIXCLOCK   4274
+#define RES_1920X1440_75HZ_PIXCLOCK   3367
+#define RES_2048X1536_60HZ_PIXCLOCK   3742
+
+#define RES_1360X768_RB_60HZ_PIXCLOCK 13889
+#define RES_1400X1050_RB_60HZ_PIXCLOCK 9901
+#define RES_1440X900_RB_60HZ_PIXCLOCK   11268
+#define RES_1600X900_RB_60HZ_PIXCLOCK   10230
+#define RES_1680X1050_RB_60HZ_PIXCLOCK 8403
+#define RES_1920X1080_RB_60HZ_PIXCLOCK 7225
+#define RES_1920X1200_RB_60HZ_PIXCLOCK 6497
+
+/* LCD display method
+*/
+#define     LCD_EXPANDSION              0x00
+#define     LCD_CENTERING               0x01
+
+/* LCD mode
+*/
+#define     LCD_OPENLDI               0x00
+#define     LCD_SPWG                  0x01
+
+/* Define display timing
+*/
+struct display_timing {
+       u16 hor_total;
+       u16 hor_addr;
+       u16 hor_blank_start;
+       u16 hor_blank_end;
+       u16 hor_sync_start;
+       u16 hor_sync_end;
+       u16 ver_total;
+       u16 ver_addr;
+       u16 ver_blank_start;
+       u16 ver_blank_end;
+       u16 ver_sync_start;
+       u16 ver_sync_end;
+};
+
+struct crt_mode_table {
+       int refresh_rate;
+       unsigned long clk;
+       int h_sync_polarity;
+       int v_sync_polarity;
+       struct display_timing crtc;
+};
+
+struct io_reg {
+       int port;
+       u8 index;
+       u8 mask;
+       u8 value;
+};
+
+#endif /* __SHARE_H__ */
diff --git a/drivers/video/via/tbl1636.c b/drivers/video/via/tbl1636.c
new file mode 100644 (file)
index 0000000..2d84534
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+struct IODATA COMMON_INIT_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       /* Set panel power sequence timing */
+       {0x10, 0xC0, 0x00},
+       /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */
+       {0x0B, 0xFF, 0x40},
+       /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */
+       {0x0C, 0xFF, 0x31},
+       /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/
+       {0x0D, 0xFF, 0x31},
+       /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */
+       {0x0E, 0xFF, 0x68},
+       /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */
+       {0x0F, 0xFF, 0x68},
+       /* LVDS output power up */
+       {0x09, 0xA0, 0xA0},
+       /* turn on back light */
+       {0x10, 0x33, 0x13}
+};
+
+struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       {0x08, 0xF0, 0xE0}      /* Input Data Mode Select */
+};
+
+struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       {0x08, 0xF0, 0x00}      /* Input Data Mode Select */
+};
+
+struct IODATA DITHERING_ENABLE_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       {0x0A, 0x70, 0x50}
+};
+
+struct IODATA DITHERING_DISABLE_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       {0x0A, 0x70, 0x00}
+};
+
+struct IODATA VDD_ON_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       {0x10, 0x20, 0x20}
+};
+
+struct IODATA VDD_OFF_TBL_VT1636[] = {
+/*  Index, Mask, Value */
+       {0x10, 0x20, 0x00}
+};
diff --git a/drivers/video/via/tbl1636.h b/drivers/video/via/tbl1636.h
new file mode 100644 (file)
index 0000000..d906055
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TBL1636_H_
+#define _TBL1636_H_
+#include "hw.h"
+
+extern struct IODATA COMMON_INIT_TBL_VT1636[8];
+extern struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[1];
+extern struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[1];
+extern struct IODATA DITHERING_ENABLE_TBL_VT1636[1];
+extern struct IODATA DITHERING_DISABLE_TBL_VT1636[1];
+extern struct IODATA VDD_ON_TBL_VT1636[1];
+extern struct IODATA VDD_OFF_TBL_VT1636[1];
+
+#endif /* _VIA_TBL1636_H_ */
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/via/tblDPASetting.c
new file mode 100644 (file)
index 0000000..0c4c8cc
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+/* For VT3324: */
+struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = {
+       /* Panel ID,       CLK_SEL_ST1[09],    CLK_SEL_ST2[08] */
+       {LCD_PANEL_ID0_640X480, 0x00, 0x00},    /* For 640x480   */
+       {LCD_PANEL_ID1_800X600, 0x00, 0x00},    /* For 800x600   */
+       {LCD_PANEL_ID2_1024X768, 0x00, 0x00},   /* For 1024x768  */
+       {LCD_PANEL_ID3_1280X768, 0x00, 0x00},   /* For 1280x768  */
+       {LCD_PANEL_ID4_1280X1024, 0x00, 0x00},  /* For 1280x1024 */
+       {LCD_PANEL_ID5_1400X1050, 0x00, 0x00},  /* For 1400x1050 */
+       {LCD_PANEL_ID6_1600X1200, 0x0B, 0x03}   /* For 1600x1200 */
+};
+
+struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = {
+/*  ClkRange, DVP0, DVP0DataDriving,  DVP0ClockDriving, DVP1,
+                                       DVP1Driving, DFPHigh, DFPLow */
+/*  CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
+                                       SR65,        CR97,    CR99   */
+       /* LCK/VCK < 30000000 will use this value */
+       {DPA_CLK_RANGE_30M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+        0x00},
+       /* 30000000 < LCK/VCK < 50000000 will use this value */
+       {DPA_CLK_RANGE_30_50M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+        0x00},
+       /* 50000000 < LCK/VCK < 70000000 will use this value */
+       {DPA_CLK_RANGE_50_70M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+        0x00},
+       /* 70000000 < LCK/VCK < 100000000 will use this value */
+       {DPA_CLK_RANGE_70_100M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+        0x00},
+       /* 100000000 < LCK/VCK < 15000000 will use this value */
+       {DPA_CLK_RANGE_100_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+        0x00},
+       /* 15000000 < LCK/VCK will use this value */
+       {DPA_CLK_RANGE_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x00,
+        0x00},
+};
+
+/* For VT3327: */
+struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = {
+       /* Panel ID,       CLK_SEL_ST1[09],    CLK_SEL_ST2[08] */
+       {LCD_PANEL_ID0_640X480, 0x00, 0x00},    /* For 640x480   */
+       {LCD_PANEL_ID1_800X600, 0x00, 0x00},    /* For 800x600   */
+       {LCD_PANEL_ID2_1024X768, 0x00, 0x00},   /* For 1024x768  */
+       {LCD_PANEL_ID3_1280X768, 0x00, 0x00},   /* For 1280x768  */
+       {LCD_PANEL_ID4_1280X1024, 0x00, 0x00},  /* For 1280x1024 */
+       {LCD_PANEL_ID5_1400X1050, 0x00, 0x00},  /* For 1400x1050 */
+       {LCD_PANEL_ID6_1600X1200, 0x00, 0x00}   /* For 1600x1200 */
+};
+
+struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = {
+/*  ClkRange,DVP0, DVP0DataDriving,  DVP0ClockDriving, DVP1,
+                                       DVP1Driving, DFPHigh,   DFPLow */
+/*   CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
+                                       SR65,        CR97,      CR99   */
+/* LCK/VCK < 30000000 will use this value */
+{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
+/* 30000000 < LCK/VCK < 50000000 will use this value */
+{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
+/* 50000000 < LCK/VCK < 70000000 will use this value */
+{DPA_CLK_RANGE_50_70M, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
+/* 70000000 < LCK/VCK < 100000000 will use this value */
+{DPA_CLK_RANGE_70_100M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x03},
+/* 100000000 < LCK/VCK < 15000000 will use this value */
+{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02},
+/* 15000000 < LCK/VCK will use this value */
+{DPA_CLK_RANGE_150M, 0x00, 0x20, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0D, 0x03},
+};
+
+/* For VT3364: */
+struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[] = {
+/*  ClkRange,DVP0, DVP0DataDriving,  DVP0ClockDriving, DVP1,
+                                       DVP1Driving, DFPHigh,   DFPLow */
+/*   CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
+                                       SR65,        CR97,      CR99   */
+/* LCK/VCK < 30000000 will use this value */
+{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 30000000 < LCK/VCK < 50000000 will use this value */
+{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 50000000 < LCK/VCK < 70000000 will use this value */
+{DPA_CLK_RANGE_50_70M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 70000000 < LCK/VCK < 100000000 will use this value */
+{DPA_CLK_RANGE_70_100M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 100000000 < LCK/VCK < 15000000 will use this value */
+{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 15000000 < LCK/VCK will use this value */
+{DPA_CLK_RANGE_150M, 0x01, 0x00, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x08},
+};
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/via/tblDPASetting.h
new file mode 100644 (file)
index 0000000..b065a83
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TBLDPASETTING_H_
+#define _TBLDPASETTING_H_
+#include "global.h"
+
+#define DPA_CLK_30M       30000000
+#define DPA_CLK_50M       50000000
+#define DPA_CLK_70M       70000000
+#define DPA_CLK_100M      100000000
+#define DPA_CLK_150M      150000000
+
+enum DPA_RANGE {
+       DPA_CLK_RANGE_30M,
+       DPA_CLK_RANGE_30_50M,
+       DPA_CLK_RANGE_50_70M,
+       DPA_CLK_RANGE_70_100M,
+       DPA_CLK_RANGE_100_150M,
+       DPA_CLK_RANGE_150M
+};
+
+extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7];
+extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6];
+extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7];
+extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[];
+extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6];
+
+#endif
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
new file mode 100644 (file)
index 0000000..0f3ed4e
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+static void via_i2c_setscl(void *data, int state)
+{
+       u8 val;
+       struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+       val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
+       if (state)
+               val |= 0x20;
+       else
+               val &= ~0x20;
+       switch (via_i2c_chan->i2c_port) {
+       case I2CPORTINDEX:
+               val |= 0x01;
+               break;
+       case GPIOPORTINDEX:
+               val |= 0x80;
+               break;
+       default:
+               DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
+       }
+       viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
+}
+
+static int via_i2c_getscl(void *data)
+{
+       struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+       if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08)
+               return 1;
+       return 0;
+}
+
+static int via_i2c_getsda(void *data)
+{
+       struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+       if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04)
+               return 1;
+       return 0;
+}
+
+static void via_i2c_setsda(void *data, int state)
+{
+       u8 val;
+       struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+       val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
+       if (state)
+               val |= 0x10;
+       else
+               val &= ~0x10;
+       switch (via_i2c_chan->i2c_port) {
+       case I2CPORTINDEX:
+               val |= 0x01;
+               break;
+       case GPIOPORTINDEX:
+               val |= 0x40;
+               break;
+       default:
+               DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
+       }
+       viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
+}
+
+int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
+{
+       u8 mm1[] = {0x00};
+       struct i2c_msg msgs[2];
+
+       *pdata = 0;
+       msgs[0].flags = 0;
+       msgs[1].flags = I2C_M_RD;
+       msgs[0].addr = msgs[1].addr = slave_addr / 2;
+       mm1[0] = index;
+       msgs[0].len = 1; msgs[1].len = 1;
+       msgs[0].buf = mm1; msgs[1].buf = pdata;
+       i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
+
+       return 0;
+}
+
+int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data)
+{
+       u8 msg[2] = { index, data };
+       struct i2c_msg msgs;
+
+       msgs.flags = 0;
+       msgs.addr = slave_addr / 2;
+       msgs.len = 2;
+       msgs.buf = msg;
+       return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1);
+}
+
+int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
+{
+       u8 mm1[] = {0x00};
+       struct i2c_msg msgs[2];
+
+       msgs[0].flags = 0;
+       msgs[1].flags = I2C_M_RD;
+       msgs[0].addr = msgs[1].addr = slave_addr / 2;
+       mm1[0] = index;
+       msgs[0].len = 1; msgs[1].len = buff_len;
+       msgs[0].buf = mm1; msgs[1].buf = buff;
+       i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
+       return 0;
+}
+
+int viafb_create_i2c_bus(void *viapar)
+{
+       int ret;
+       struct viafb_par *par = (struct viafb_par *)viapar;
+
+       strcpy(par->i2c_stuff.adapter.name, "via_i2c");
+       par->i2c_stuff.i2c_port = 0x0;
+       par->i2c_stuff.adapter.owner = THIS_MODULE;
+       par->i2c_stuff.adapter.id = 0x01FFFF;
+       par->i2c_stuff.adapter.class = 0;
+       par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo;
+       par->i2c_stuff.adapter.dev.parent = NULL;
+       par->i2c_stuff.algo.setsda = via_i2c_setsda;
+       par->i2c_stuff.algo.setscl = via_i2c_setscl;
+       par->i2c_stuff.algo.getsda = via_i2c_getsda;
+       par->i2c_stuff.algo.getscl = via_i2c_getscl;
+       par->i2c_stuff.algo.udelay = 40;
+       par->i2c_stuff.algo.timeout = 20;
+       par->i2c_stuff.algo.data = &par->i2c_stuff;
+
+       i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff);
+
+       /* Raise SCL and SDA */
+       par->i2c_stuff.i2c_port = I2CPORTINDEX;
+       via_i2c_setsda(&par->i2c_stuff, 1);
+       via_i2c_setscl(&par->i2c_stuff, 1);
+
+       par->i2c_stuff.i2c_port = GPIOPORTINDEX;
+       via_i2c_setsda(&par->i2c_stuff, 1);
+       via_i2c_setscl(&par->i2c_stuff, 1);
+       udelay(20);
+
+       ret = i2c_bit_add_bus(&par->i2c_stuff.adapter);
+       if (ret == 0)
+               DEBUG_MSG("I2C bus %s registered.\n",
+               par->i2c_stuff.adapter.name);
+       else
+               DEBUG_MSG("Failed to register I2C bus %s.\n",
+                       par->i2c_stuff.adapter.name);
+       return ret;
+}
+
+void viafb_delete_i2c_buss(void *par)
+{
+       i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter);
+}
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h
new file mode 100644 (file)
index 0000000..3a13242
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __VIA_I2C_H__
+#define __VIA_I2C_H__
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+struct via_i2c_stuff {
+       u16 i2c_port;                   /* GPIO or I2C port */
+       struct i2c_adapter adapter;
+       struct i2c_algo_bit_data algo;
+};
+
+#define I2CPORT           0x3c4
+#define I2CPORTINDEX      0x31
+#define GPIOPORT          0x3C4
+#define GPIOPORTINDEX     0x2C
+#define I2C_BUS             1
+#define GPIO_BUS            2
+#define DELAYPORT           0x3C3
+
+int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata);
+int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data);
+int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len);
+int viafb_create_i2c_bus(void *par);
+void viafb_delete_i2c_buss(void *par);
+#endif /* __VIA_I2C_H__ */
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c
new file mode 100644 (file)
index 0000000..d53c3d5
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+void viafb_get_device_support_state(u32 *support_state)
+{
+       *support_state = CRT_Device;
+
+       if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS)
+               *support_state |= DVI_Device;
+
+       if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS)
+               *support_state |= LCD_Device;
+}
+
+void viafb_get_device_connect_state(u32 *connect_state)
+{
+       bool mobile = false;
+
+       *connect_state = CRT_Device;
+
+       if (viafb_dvi_sense())
+               *connect_state |= DVI_Device;
+
+       viafb_lcd_get_mobile_state(&mobile);
+       if (mobile)
+               *connect_state |= LCD_Device;
+}
+
+bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres)
+{
+       unsigned int support_state = 0;
+
+       switch (viafb_lcd_panel_id) {
+       case LCD_PANEL_ID0_640X480:
+               if ((xres < 640) && (yres < 480))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID1_800X600:
+               if ((xres < 800) && (yres < 600))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID2_1024X768:
+               if ((xres < 1024) && (yres < 768))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID3_1280X768:
+               if ((xres < 1280) && (yres < 768))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID4_1280X1024:
+               if ((xres < 1280) && (yres < 1024))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID5_1400X1050:
+               if ((xres < 1400) && (yres < 1050))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID6_1600X1200:
+               if ((xres < 1600) && (yres < 1200))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID7_1366X768:
+               if ((xres < 1366) && (yres < 768))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID8_1024X600:
+               if ((xres < 1024) && (yres < 600))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_ID9_1280X800:
+               if ((xres < 1280) && (yres < 800))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_IDA_800X480:
+               if ((xres < 800) && (yres < 480))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_IDB_1360X768:
+               if ((xres < 1360) && (yres < 768))
+                       support_state = true;
+               break;
+
+       case LCD_PANEL_IDC_480X640:
+               if ((xres < 480) && (yres < 640))
+                       support_state = true;
+               break;
+
+       default:
+               support_state = false;
+               break;
+       }
+
+       return support_state;
+}
+
+/*====================================================================*/
+/*                      Gamma Function Implementation*/
+/*====================================================================*/
+
+void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
+{
+       int i, sr1a;
+       int active_device_amount = 0;
+       int device_status = viafb_DeviceStatus;
+
+       for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) {
+               if (device_status & 1)
+                       active_device_amount++;
+               device_status >>= 1;
+       }
+
+       /* 8 bpp mode can't adjust gamma */
+       if (bpp == 8)
+               return ;
+
+       /* Enable Gamma */
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_CLE266:
+       case UNICHROME_K400:
+               viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
+               break;
+
+       case UNICHROME_K800:
+       case UNICHROME_PM800:
+       case UNICHROME_CN700:
+       case UNICHROME_CX700:
+       case UNICHROME_K8M890:
+       case UNICHROME_P4M890:
+       case UNICHROME_P4M900:
+               viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
+               break;
+       }
+       sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A);
+       viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
+
+       /* Fill IGA1 Gamma Table */
+       outb(0, LUT_INDEX_WRITE);
+       for (i = 0; i < 256; i++) {
+               outb(gamma_table[i] >> 16, LUT_DATA);
+               outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
+               outb(gamma_table[i] & 0xFF, LUT_DATA);
+       }
+
+       /* If adjust Gamma value in SAMM, fill IGA1,
+          IGA2 Gamma table simultanous. */
+       /* Switch to IGA2 Gamma Table */
+       if ((active_device_amount > 1) &&
+               !((viaparinfo->chip_info->gfx_chip_name ==
+               UNICHROME_CLE266) &&
+               (viaparinfo->chip_info->gfx_chip_revision < 15))) {
+               viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
+               viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1);
+
+               /* Fill IGA2 Gamma Table */
+               outb(0, LUT_INDEX_WRITE);
+               for (i = 0; i < 256; i++) {
+                       outb(gamma_table[i] >> 16, LUT_DATA);
+                       outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
+                       outb(gamma_table[i] & 0xFF, LUT_DATA);
+               }
+       }
+       viafb_write_reg(SR1A, VIASR, sr1a);
+}
+
+void viafb_get_gamma_table(unsigned int *gamma_table)
+{
+       unsigned char color_r, color_g, color_b;
+       unsigned char sr1a = 0;
+       int i;
+
+       /* Enable Gamma */
+       switch (viaparinfo->chip_info->gfx_chip_name) {
+       case UNICHROME_CLE266:
+       case UNICHROME_K400:
+               viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
+               break;
+
+       case UNICHROME_K800:
+       case UNICHROME_PM800:
+       case UNICHROME_CN700:
+       case UNICHROME_CX700:
+       case UNICHROME_K8M890:
+       case UNICHROME_P4M890:
+       case UNICHROME_P4M900:
+               viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
+               break;
+       }
+       sr1a = viafb_read_reg(VIASR, SR1A);
+       viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
+
+       /* Reading gamma table to get color value */
+       outb(0, LUT_INDEX_READ);
+       for (i = 0; i < 256; i++) {
+               color_r = inb(LUT_DATA);
+               color_g = inb(LUT_DATA);
+               color_b = inb(LUT_DATA);
+               gamma_table[i] =
+                   ((((u32) color_r) << 16) |
+                    (((u16) color_g) << 8)) | color_b;
+       }
+       viafb_write_reg(SR1A, VIASR, sr1a);
+}
+
+void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
+{
+       if (bpp == 8)
+               *support_state = None_Device;
+       else
+               *support_state = CRT_Device | DVI_Device | LCD_Device;
+}
+
+int viafb_input_parameter_converter(int parameter_value)
+{
+       int result;
+
+       if (parameter_value >= 1 && parameter_value <= 9)
+               result = 1 << (parameter_value - 1);
+       else
+               result = 1;
+
+       return result;
+}
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h
new file mode 100644 (file)
index 0000000..2fd4552
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __VIAUTILITY_H__
+#define __VIAUTILITY_H__
+
+/* These functions are used to get infomation about device's state */
+void viafb_get_device_support_state(u32 *support_state);
+void viafb_get_device_connect_state(u32 *connect_state);
+bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres);
+
+/* These function are used to access gamma table */
+void viafb_set_gamma_table(int bpp, unsigned int *gamma_table);
+void viafb_get_gamma_table(unsigned int *gamma_table);
+void viafb_get_gamma_support_state(int bpp, unsigned int *support_state);
+int viafb_input_parameter_converter(int parameter_value);
+
+#endif /* __VIAUTILITY_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
new file mode 100644 (file)
index 0000000..0132eae
--- /dev/null
@@ -0,0 +1,2571 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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/module.h>
+#define _MASTER_FILE
+
+#include "global.h"
+
+static int MAX_CURS = 32;
+static struct fb_var_screeninfo default_var;
+static char *viafb_name = "Via";
+static u32 pseudo_pal[17];
+
+/* video mode */
+static char *viafb_mode = "640x480";
+static char *viafb_mode1 = "640x480";
+static int viafb_resMode = VIA_RES_640X480;
+
+/* Added for specifying active devices.*/
+char *viafb_active_dev = "";
+
+/* Added for specifying video on devices.*/
+char *viafb_video_dev = "";
+
+/*Added for specify lcd output port*/
+char *viafb_lcd_port = "";
+char *viafb_dvi_port = "";
+
+static void viafb_set_device(struct device_t active_dev);
+static int apply_device_setting(struct viafb_ioctl_setting setting_info,
+                        struct fb_info *info);
+static void apply_second_mode_setting(struct fb_var_screeninfo
+       *sec_var);
+static void retrieve_device_setting(struct viafb_ioctl_setting
+       *setting_info);
+static void viafb_set_video_device(u32 video_dev_info);
+static void viafb_get_video_device(u32 *video_dev_info);
+
+/* Mode information */
+static const struct viafb_modeinfo viafb_modentry[] = {
+       {480, 640, VIA_RES_480X640, "480x640"},
+       {640, 480, VIA_RES_640X480, "640x480"},
+       {800, 480, VIA_RES_800X480, "800x480"},
+       {800, 600, VIA_RES_800X600, "800x600"},
+       {1024, 768, VIA_RES_1024X768, "1024x768"},
+       {1152, 864, VIA_RES_1152X864, "1152x864"},
+       {1280, 1024, VIA_RES_1280X1024, "1280x1024"},
+       {1600, 1200, VIA_RES_1600X1200, "1600x1200"},
+       {1440, 1050, VIA_RES_1440X1050, "1440x1050"},
+       {1280, 768, VIA_RES_1280X768, "1280x768"},
+       {1280, 800, VIA_RES_1280X800, "1280x800"},
+       {1280, 960, VIA_RES_1280X960, "1280x960"},
+       {1920, 1440, VIA_RES_1920X1440, "1920x1440"},
+       {848, 480, VIA_RES_848X480, "848x480"},
+       {1400, 1050, VIA_RES_1400X1050, "1400x1050"},
+       {720, 480, VIA_RES_720X480, "720x480"},
+       {720, 576, VIA_RES_720X576, "720x576"},
+       {1024, 512, VIA_RES_1024X512, "1024x512"},
+       {1024, 576, VIA_RES_1024X576, "1024x576"},
+       {1024, 600, VIA_RES_1024X600, "1024x600"},
+       {1280, 720, VIA_RES_1280X720, "1280x720"},
+       {1920, 1080, VIA_RES_1920X1080, "1920x1080"},
+       {1366, 768, VIA_RES_1368X768, "1368x768"},
+       {1680, 1050, VIA_RES_1680X1050, "1680x1050"},
+       {960, 600, VIA_RES_960X600, "960x600"},
+       {1000, 600, VIA_RES_1000X600, "1000x600"},
+       {1024, 576, VIA_RES_1024X576, "1024x576"},
+       {1024, 600, VIA_RES_1024X600, "1024x600"},
+       {1088, 612, VIA_RES_1088X612, "1088x612"},
+       {1152, 720, VIA_RES_1152X720, "1152x720"},
+       {1200, 720, VIA_RES_1200X720, "1200x720"},
+       {1280, 600, VIA_RES_1280X600, "1280x600"},
+       {1360, 768, VIA_RES_1360X768, "1360x768"},
+       {1440, 900, VIA_RES_1440X900, "1440x900"},
+       {1600, 900, VIA_RES_1600X900, "1600x900"},
+       {1600, 1024, VIA_RES_1600X1024, "1600x1024"},
+       {1792, 1344, VIA_RES_1792X1344, "1792x1344"},
+       {1856, 1392, VIA_RES_1856X1392, "1856x1392"},
+       {1920, 1200, VIA_RES_1920X1200, "1920x1200"},
+       {2048, 1536, VIA_RES_2048X1536, "2048x1536"},
+       {0, 0, VIA_RES_INVALID, "640x480"}
+};
+
+static struct fb_ops viafb_ops;
+
+static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
+{
+       struct viafb_par *ppar;
+       ppar = info->par;
+
+       DEBUG_MSG(KERN_INFO "viafb_update_fix!\n");
+
+       fix->visual =
+           ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+       fix->line_length = ppar->linelength;
+
+       return 0;
+}
+
+
+static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
+       struct viafb_par *viaparinfo)
+{
+       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+       strcpy(fix->id, viafb_name);
+
+       fix->smem_start = viaparinfo->fbmem;
+       fix->smem_len = viaparinfo->fbmem_free;
+       fix->mmio_start = viaparinfo->mmio_base;
+       fix->mmio_len = viaparinfo->mmio_len;
+
+       fix->type = FB_TYPE_PACKED_PIXELS;
+       fix->type_aux = 0;
+
+       fix->xpanstep = fix->ywrapstep = 0;
+       fix->ypanstep = 1;
+
+       /* Just tell the accel name */
+       viafbinfo->fix.accel = FB_ACCEL_VIA_UNICHROME;
+}
+static int viafb_open(struct fb_info *info, int user)
+{
+       DEBUG_MSG(KERN_INFO "viafb_open!\n");
+       return 0;
+}
+
+static int viafb_release(struct fb_info *info, int user)
+{
+       DEBUG_MSG(KERN_INFO "viafb_release!\n");
+       return 0;
+}
+
+static void viafb_update_viafb_par(struct fb_info *info)
+{
+       struct viafb_par *ppar;
+
+       ppar = info->par;
+       ppar->bpp = info->var.bits_per_pixel;
+       ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8;
+       ppar->hres = info->var.xres;
+       ppar->vres = info->var.yres;
+       ppar->xoffset = info->var.xoffset;
+       ppar->yoffset = info->var.yoffset;
+}
+
+static int viafb_check_var(struct fb_var_screeninfo *var,
+       struct fb_info *info)
+{
+       int vmode_index, htotal, vtotal;
+       struct viafb_par *ppar;
+       u32 long_refresh;
+       struct viafb_par *p_viafb_par;
+       ppar = info->par;
+
+
+       DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
+       /* Sanity check */
+       /* HW neither support interlacte nor double-scaned mode */
+       if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
+               return -EINVAL;
+
+       vmode_index = viafb_get_mode_index(var->xres, var->yres, 0);
+       if (vmode_index == VIA_RES_INVALID) {
+               DEBUG_MSG(KERN_INFO
+                         "viafb: Mode %dx%dx%d not supported!!\n",
+                         var->xres, var->yres, var->bits_per_pixel);
+               return -EINVAL;
+       }
+
+       if (24 == var->bits_per_pixel)
+               var->bits_per_pixel = 32;
+
+       if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 &&
+               var->bits_per_pixel != 32)
+               return -EINVAL;
+
+       if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F)
+               /*32 pixel alignment */
+               var->xres_virtual = (var->xres_virtual + 31) & ~31;
+       if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
+               ppar->memsize)
+               return -EINVAL;
+
+       /* Based on var passed in to calculate the refresh,
+        * because our driver use some modes special.
+        */
+       htotal = var->xres + var->left_margin +
+       var->right_margin + var->hsync_len;
+       vtotal = var->yres + var->upper_margin +
+               var->lower_margin + var->vsync_len;
+       long_refresh = 1000000000UL / var->pixclock * 1000;
+       long_refresh /= (htotal * vtotal);
+
+       viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
+
+       /* Adjust var according to our driver's own table */
+       viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
+
+       /* This is indeed a patch for VT3353 */
+       if (!info->par)
+               return -1;
+       p_viafb_par = (struct viafb_par *)info->par;
+       if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800)
+               var->accel_flags = 0;
+
+       return 0;
+}
+
+static int viafb_set_par(struct fb_info *info)
+{
+       int vmode_index;
+       int vmode_index1 = 0;
+       DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
+
+       viafb_update_device_setting(info->var.xres, info->var.yres,
+                             info->var.bits_per_pixel, viafb_refresh, 0);
+
+       vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0);
+
+       if (viafb_SAMM_ON == 1) {
+               DEBUG_MSG(KERN_INFO
+               "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
+                         viafb_second_xres, viafb_second_yres, viafb_bpp1);
+               vmode_index1 = viafb_get_mode_index(viafb_second_xres,
+                       viafb_second_yres, 1);
+               DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",
+                       vmode_index1);
+
+               viafb_update_device_setting(viafb_second_xres,
+                       viafb_second_yres, viafb_bpp1, viafb_refresh1, 1);
+       }
+
+       if (vmode_index != VIA_RES_INVALID) {
+               viafb_setmode(vmode_index, info->var.xres, info->var.yres,
+                       info->var.bits_per_pixel, vmode_index1,
+                       viafb_second_xres, viafb_second_yres, viafb_bpp1);
+
+               /*We should set memory offset according virtual_x */
+               /*Fix me:put this function into viafb_setmode */
+               viafb_memory_pitch_patch(info);
+
+               /* Update ***fb_par information */
+               viafb_update_viafb_par(info);
+
+               /* Update other fixed information */
+               viafb_update_fix(&info->fix, info);
+               viafb_bpp = info->var.bits_per_pixel;
+               /* Update viafb_accel, it is necessary to our 2D accelerate */
+               viafb_accel = info->var.accel_flags;
+
+               if (viafb_accel)
+                       viafb_set_2d_color_depth(info->var.bits_per_pixel);
+       }
+
+       return 0;
+}
+
+/* Set one color register */
+static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+unsigned blue, unsigned transp, struct fb_info *info)
+{
+       u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
+       unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16;
+       DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n");
+       if (regno >= cmap_entries)
+               return 1;
+       if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
+               /*
+                * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev.
+                */
+               outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
+               rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
+       }
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               outb(0x1A, 0x3C4);
+               sr1a = inb(0x3C5);
+               outb(0x1B, 0x3C4);
+               sr1b = inb(0x3C5);
+               outb(0x67, 0x3D4);
+               cr67 = inb(0x3D5);
+               outb(0x6A, 0x3D4);
+               cr6a = inb(0x3D5);
+
+               /* Map the 3C6/7/8/9 to the IGA2 */
+               outb(0x1A, 0x3C4);
+               outb(sr1a | 0x01, 0x3C5);
+               /* Second Display Engine colck always on */
+               outb(0x1B, 0x3C4);
+               outb(sr1b | 0x80, 0x3C5);
+               /* Second Display Color Depth 8 */
+               outb(0x67, 0x3D4);
+               outb(cr67 & 0x3F, 0x3D5);
+               outb(0x6A, 0x3D4);
+               /* Second Display Channel Reset CR6A[6]) */
+               outb(cr6a & 0xBF, 0x3D5);
+               /* Second Display Channel Enable CR6A[7] */
+               outb(cr6a | 0x80, 0x3D5);
+               /* Second Display Channel stop reset) */
+               outb(cr6a | 0x40, 0x3D5);
+
+               /* Bit mask of palette */
+               outb(0xFF, 0x3c6);
+               /* Write one register of IGA2 */
+               outb(regno, 0x3C8);
+               if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
+                       rev >= 15) {
+                       shift = 8;
+                       viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
+                       viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
+               } else {
+                       shift = 10;
+                       viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
+                       viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
+               }
+               outb(red >> shift, 0x3C9);
+               outb(green >> shift, 0x3C9);
+               outb(blue >> shift, 0x3C9);
+
+               /* Map the 3C6/7/8/9 to the IGA1 */
+               outb(0x1A, 0x3C4);
+               outb(sr1a & 0xFE, 0x3C5);
+               /* Bit mask of palette */
+               outb(0xFF, 0x3c6);
+               /* Write one register of IGA1 */
+               outb(regno, 0x3C8);
+               outb(red >> shift, 0x3C9);
+               outb(green >> shift, 0x3C9);
+               outb(blue >> shift, 0x3C9);
+
+               outb(0x1A, 0x3C4);
+               outb(sr1a, 0x3C5);
+               outb(0x1B, 0x3C4);
+               outb(sr1b, 0x3C5);
+               outb(0x67, 0x3D4);
+               outb(cr67, 0x3D5);
+               outb(0x6A, 0x3D4);
+               outb(cr6a, 0x3D5);
+               break;
+       case 16:
+               ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) |
+                   ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
+               break;
+       case 32:
+               ((u32 *) info->pseudo_palette)[regno] =
+                   ((transp & 0xFF00) << 16) |
+                   ((red & 0xFF00) << 8) |
+                   ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
+               break;
+       }
+
+       return 0;
+
+}
+
+/*CALLED BY: fb_set_cmap */
+/*           fb_set_var, pass 256 colors */
+/*CALLED BY: fb_set_cmap */
+/*           fbcon_set_palette, pass 16 colors */
+static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+       u32 len = cmap->len;
+       u32 i;
+       u16 *pred = cmap->red;
+       u16 *pgreen = cmap->green;
+       u16 *pblue = cmap->blue;
+       u16 *ptransp = cmap->transp;
+       u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
+       if (len > 256)
+               return 1;
+       if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
+               /*
+                * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip
+                * rev.
+                */
+               outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
+               rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
+       }
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               outb(0x1A, 0x3C4);
+               sr1a = inb(0x3C5);
+               outb(0x1B, 0x3C4);
+               sr1b = inb(0x3C5);
+               outb(0x67, 0x3D4);
+               cr67 = inb(0x3D5);
+               outb(0x6A, 0x3D4);
+               cr6a = inb(0x3D5);
+               /* Map the 3C6/7/8/9 to the IGA2 */
+               outb(0x1A, 0x3C4);
+               outb(sr1a | 0x01, 0x3C5);
+               outb(0x1B, 0x3C4);
+               /* Second Display Engine colck always on */
+               outb(sr1b | 0x80, 0x3C5);
+               outb(0x67, 0x3D4);
+               /* Second Display Color Depth 8 */
+               outb(cr67 & 0x3F, 0x3D5);
+               outb(0x6A, 0x3D4);
+               /* Second Display Channel Reset CR6A[6]) */
+               outb(cr6a & 0xBF, 0x3D5);
+               /* Second Display Channel Enable CR6A[7] */
+               outb(cr6a | 0x80, 0x3D5);
+               /* Second Display Channel stop reset) */
+               outb(cr6a | 0xC0, 0x3D5);
+
+               /* Bit mask of palette */
+               outb(0xFF, 0x3c6);
+               outb(0x00, 0x3C8);
+               if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
+                       rev >= 15) {
+                       shift = 8;
+                       viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
+                       viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
+               } else {
+                       shift = 10;
+                       viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
+                       viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
+               }
+               for (i = 0; i < len; i++) {
+                       outb((*(pred + i)) >> shift, 0x3C9);
+                       outb((*(pgreen + i)) >> shift, 0x3C9);
+                       outb((*(pblue + i)) >> shift, 0x3C9);
+               }
+
+               outb(0x1A, 0x3C4);
+               /* Map the 3C6/7/8/9 to the IGA1 */
+               outb(sr1a & 0xFE, 0x3C5);
+               /* Bit mask of palette */
+               outb(0xFF, 0x3c6);
+               outb(0x00, 0x3C8);
+               for (i = 0; i < len; i++) {
+                       outb((*(pred + i)) >> shift, 0x3C9);
+                       outb((*(pgreen + i)) >> shift, 0x3C9);
+                       outb((*(pblue + i)) >> shift, 0x3C9);
+               }
+
+               outb(0x1A, 0x3C4);
+               outb(sr1a, 0x3C5);
+               outb(0x1B, 0x3C4);
+               outb(sr1b, 0x3C5);
+               outb(0x67, 0x3D4);
+               outb(cr67, 0x3D5);
+               outb(0x6A, 0x3D4);
+               outb(cr6a, 0x3D5);
+               break;
+       case 16:
+               if (len > 17)
+                       return 0;       /* Because static u32 pseudo_pal[17]; */
+               for (i = 0; i < len; i++)
+                       ((u32 *) info->pseudo_palette)[i] =
+                           (*(pred + i) & 0xF800) |
+                           ((*(pgreen + i) & 0xFC00) >> 5) |
+                           ((*(pblue + i) & 0xF800) >> 11);
+               break;
+       case 32:
+               if (len > 17)
+                       return 0;
+               if (ptransp) {
+                       for (i = 0; i < len; i++)
+                               ((u32 *) info->pseudo_palette)[i] =
+                                   ((*(ptransp + i) & 0xFF00) << 16) |
+                                   ((*(pred + i) & 0xFF00) << 8) |
+                                   ((*(pgreen + i) & 0xFF00)) |
+                                   ((*(pblue + i) & 0xFF00) >> 8);
+               } else {
+                       for (i = 0; i < len; i++)
+                               ((u32 *) info->pseudo_palette)[i] =
+                                   0x00000000 |
+                                   ((*(pred + i) & 0xFF00) << 8) |
+                                   ((*(pgreen + i) & 0xFF00)) |
+                                   ((*(pblue + i) & 0xFF00) >> 8);
+               }
+               break;
+       }
+       return 0;
+}
+
+static int viafb_pan_display(struct fb_var_screeninfo *var,
+       struct fb_info *info)
+{
+       unsigned int offset;
+
+       DEBUG_MSG(KERN_INFO "viafb_pan_display!\n");
+
+       offset = (var->xoffset + (var->yoffset * var->xres_virtual)) *
+           var->bits_per_pixel / 16;
+
+       DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);
+
+       viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3);
+       viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff);
+       viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff);
+       viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff);
+
+       return 0;
+}
+
+static int viafb_blank(int blank_mode, struct fb_info *info)
+{
+       DEBUG_MSG(KERN_INFO "viafb_blank!\n");
+       /* clear DPMS setting */
+
+       switch (blank_mode) {
+       case FB_BLANK_UNBLANK:
+               /* Screen: On, HSync: On, VSync: On */
+               /* control CRT monitor power management */
+               viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
+               break;
+       case FB_BLANK_HSYNC_SUSPEND:
+               /* Screen: Off, HSync: Off, VSync: On */
+               /* control CRT monitor power management */
+               viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5);
+               break;
+       case FB_BLANK_VSYNC_SUSPEND:
+               /* Screen: Off, HSync: On, VSync: Off */
+               /* control CRT monitor power management */
+               viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5);
+               break;
+       case FB_BLANK_POWERDOWN:
+               /* Screen: Off, HSync: Off, VSync: Off */
+               /* control CRT monitor power management */
+               viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5);
+               break;
+       }
+
+       return 0;
+}
+
+static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
+{
+       struct viafb_ioctl_mode viamode;
+       struct viafb_ioctl_samm viasamm;
+       struct viafb_driver_version driver_version;
+       struct fb_var_screeninfo sec_var;
+       struct _panel_size_pos_info panel_pos_size_para;
+       u32 state_info = 0;
+       u32 viainfo_size = sizeof(struct viafb_ioctl_info);
+       u32 *viafb_gamma_table;
+       char driver_name[] = "viafb";
+
+       u32 __user *argp = (u32 __user *) arg;
+       u32 gpu32;
+       u32 video_dev_info = 0;
+       struct viafb_ioctl_setting viafb_setting = {};
+       struct device_t active_dev = {};
+
+       DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
+
+       switch (cmd) {
+       case VIAFB_GET_CHIP_INFO:
+               if (copy_to_user(argp, viaparinfo->chip_info,
+                               sizeof(struct chip_information)))
+                       return -EFAULT;
+               break;
+       case VIAFB_GET_INFO_SIZE:
+               return put_user(viainfo_size, argp);
+       case VIAFB_GET_INFO:
+               return viafb_ioctl_get_viafb_info(arg);
+       case VIAFB_HOTPLUG:
+               return put_user(viafb_ioctl_hotplug(info->var.xres,
+                                             info->var.yres,
+                                             info->var.bits_per_pixel), argp);
+       case VIAFB_SET_HOTPLUG_FLAG:
+               if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
+                       return -EFAULT;
+               viafb_hotplug = (gpu32) ? 1 : 0;
+               break;
+       case VIAFB_GET_RESOLUTION:
+               viamode.xres = (u32) viafb_hotplug_Xres;
+               viamode.yres = (u32) viafb_hotplug_Yres;
+               viamode.refresh = (u32) viafb_hotplug_refresh;
+               viamode.bpp = (u32) viafb_hotplug_bpp;
+               if (viafb_SAMM_ON == 1) {
+                       viamode.xres_sec = viafb_second_xres;
+                       viamode.yres_sec = viafb_second_yres;
+                       viamode.virtual_xres_sec = viafb_second_virtual_xres;
+                       viamode.virtual_yres_sec = viafb_second_virtual_yres;
+                       viamode.refresh_sec = viafb_refresh1;
+                       viamode.bpp_sec = viafb_bpp1;
+               } else {
+                       viamode.xres_sec = 0;
+                       viamode.yres_sec = 0;
+                       viamode.virtual_xres_sec = 0;
+                       viamode.virtual_yres_sec = 0;
+                       viamode.refresh_sec = 0;
+                       viamode.bpp_sec = 0;
+               }
+               if (copy_to_user(argp, &viamode, sizeof(viamode)))
+                       return -EFAULT;
+               break;
+       case VIAFB_GET_SAMM_INFO:
+               viasamm.samm_status = viafb_SAMM_ON;
+
+               if (viafb_SAMM_ON == 1) {
+                       if (viafb_dual_fb) {
+                               viasamm.size_prim = viaparinfo->fbmem_free;
+                               viasamm.size_sec = viaparinfo1->fbmem_free;
+                       } else {
+                               if (viafb_second_size) {
+                                       viasamm.size_prim =
+                                           viaparinfo->fbmem_free -
+                                           viafb_second_size * 1024 * 1024;
+                                       viasamm.size_sec =
+                                           viafb_second_size * 1024 * 1024;
+                               } else {
+                                       viasamm.size_prim =
+                                           viaparinfo->fbmem_free >> 1;
+                                       viasamm.size_sec =
+                                           (viaparinfo->fbmem_free >> 1);
+                               }
+                       }
+                       viasamm.mem_base = viaparinfo->fbmem;
+                       viasamm.offset_sec = viafb_second_offset;
+               } else {
+                       viasamm.size_prim =
+                           viaparinfo->memsize - viaparinfo->fbmem_used;
+                       viasamm.size_sec = 0;
+                       viasamm.mem_base = viaparinfo->fbmem;
+                       viasamm.offset_sec = 0;
+               }
+
+               if (copy_to_user(argp, &viasamm, sizeof(viasamm)))
+                       return -EFAULT;
+
+               break;
+       case VIAFB_TURN_ON_OUTPUT_DEVICE:
+               if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
+                       return -EFAULT;
+               if (gpu32 & CRT_Device)
+                       viafb_crt_enable();
+               if (gpu32 & DVI_Device)
+                       viafb_dvi_enable();
+               if (gpu32 & LCD_Device)
+                       viafb_lcd_enable();
+               break;
+       case VIAFB_TURN_OFF_OUTPUT_DEVICE:
+               if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
+                       return -EFAULT;
+               if (gpu32 & CRT_Device)
+                       viafb_crt_disable();
+               if (gpu32 & DVI_Device)
+                       viafb_dvi_disable();
+               if (gpu32 & LCD_Device)
+                       viafb_lcd_disable();
+               break;
+       case VIAFB_SET_DEVICE:
+               if (copy_from_user(&active_dev, (void *)argp,
+                       sizeof(active_dev)))
+                       return -EFAULT;
+               viafb_set_device(active_dev);
+               viafb_set_par(info);
+               break;
+       case VIAFB_GET_DEVICE:
+               active_dev.crt = viafb_CRT_ON;
+               active_dev.dvi = viafb_DVI_ON;
+               active_dev.lcd = viafb_LCD_ON;
+               active_dev.samm = viafb_SAMM_ON;
+               active_dev.primary_dev = viafb_primary_dev;
+
+               active_dev.lcd_dsp_cent = viafb_lcd_dsp_method;
+               active_dev.lcd_panel_id = viafb_lcd_panel_id;
+               active_dev.lcd_mode = viafb_lcd_mode;
+
+               active_dev.xres = viafb_hotplug_Xres;
+               active_dev.yres = viafb_hotplug_Yres;
+
+               active_dev.xres1 = viafb_second_xres;
+               active_dev.yres1 = viafb_second_yres;
+
+               active_dev.bpp = viafb_bpp;
+               active_dev.bpp1 = viafb_bpp1;
+               active_dev.refresh = viafb_refresh;
+               active_dev.refresh1 = viafb_refresh1;
+
+               active_dev.epia_dvi = viafb_platform_epia_dvi;
+               active_dev.lcd_dual_edge = viafb_device_lcd_dualedge;
+               active_dev.bus_width = viafb_bus_width;
+
+               if (copy_to_user(argp, &active_dev, sizeof(active_dev)))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_GET_DRIVER_VERSION:
+               driver_version.iMajorNum = VERSION_MAJOR;
+               driver_version.iKernelNum = VERSION_KERNEL;
+               driver_version.iOSNum = VERSION_OS;
+               driver_version.iMinorNum = VERSION_MINOR;
+
+               if (copy_to_user(argp, &driver_version,
+                       sizeof(driver_version)))
+                       return -EFAULT;
+
+               break;
+
+       case VIAFB_SET_DEVICE_INFO:
+               if (copy_from_user(&viafb_setting,
+                       argp, sizeof(viafb_setting)))
+                       return -EFAULT;
+               if (apply_device_setting(viafb_setting, info) < 0)
+                       return -EINVAL;
+
+               break;
+
+       case VIAFB_SET_SECOND_MODE:
+               if (copy_from_user(&sec_var, argp, sizeof(sec_var)))
+                       return -EFAULT;
+               apply_second_mode_setting(&sec_var);
+               break;
+
+       case VIAFB_GET_DEVICE_INFO:
+
+               retrieve_device_setting(&viafb_setting);
+
+               if (copy_to_user(argp, &viafb_setting, sizeof(viafb_setting)))
+                       return -EFAULT;
+
+               break;
+
+       case VIAFB_GET_DEVICE_SUPPORT:
+               viafb_get_device_support_state(&state_info);
+               if (put_user(state_info, argp))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_GET_DEVICE_CONNECT:
+               viafb_get_device_connect_state(&state_info);
+               if (put_user(state_info, argp))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_GET_PANEL_SUPPORT_EXPAND:
+               state_info =
+                   viafb_lcd_get_support_expand_state(info->var.xres,
+                                                info->var.yres);
+               if (put_user(state_info, argp))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_GET_DRIVER_NAME:
+               if (copy_to_user(argp, driver_name, sizeof(driver_name)))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_SET_GAMMA_LUT:
+               viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);
+               if (!viafb_gamma_table)
+                       return -ENOMEM;
+               if (copy_from_user(viafb_gamma_table, argp,
+                               sizeof(viafb_gamma_table))) {
+                       kfree(viafb_gamma_table);
+                       return -EFAULT;
+               }
+               viafb_set_gamma_table(viafb_bpp, viafb_gamma_table);
+               kfree(viafb_gamma_table);
+               break;
+
+       case VIAFB_GET_GAMMA_LUT:
+               viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);
+               if (!viafb_gamma_table)
+                       return -ENOMEM;
+               viafb_get_gamma_table(viafb_gamma_table);
+               if (copy_to_user(argp, viafb_gamma_table,
+                       sizeof(viafb_gamma_table))) {
+                       kfree(viafb_gamma_table);
+                       return -EFAULT;
+               }
+               kfree(viafb_gamma_table);
+               break;
+
+       case VIAFB_GET_GAMMA_SUPPORT_STATE:
+               viafb_get_gamma_support_state(viafb_bpp, &state_info);
+               if (put_user(state_info, argp))
+                       return -EFAULT;
+               break;
+       case VIAFB_SET_VIDEO_DEVICE:
+               get_user(video_dev_info, argp);
+               viafb_set_video_device(video_dev_info);
+               break;
+       case VIAFB_GET_VIDEO_DEVICE:
+               viafb_get_video_device(&video_dev_info);
+               if (put_user(video_dev_info, argp))
+                       return -EFAULT;
+               break;
+       case VIAFB_SYNC_SURFACE:
+               DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n");
+               break;
+       case VIAFB_GET_DRIVER_CAPS:
+               break;
+
+       case VIAFB_GET_PANEL_MAX_SIZE:
+               if (copy_from_user
+                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               panel_pos_size_para.x = panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &panel_pos_size_para,
+                    sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               break;
+       case VIAFB_GET_PANEL_MAX_POSITION:
+               if (copy_from_user
+                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               panel_pos_size_para.x = panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &panel_pos_size_para,
+                    sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_GET_PANEL_POSITION:
+               if (copy_from_user
+                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               panel_pos_size_para.x = panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &panel_pos_size_para,
+                    sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               break;
+       case VIAFB_GET_PANEL_SIZE:
+               if (copy_from_user
+                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               panel_pos_size_para.x = panel_pos_size_para.y = 0;
+               if (copy_to_user(argp, &panel_pos_size_para,
+                    sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               break;
+
+       case VIAFB_SET_PANEL_POSITION:
+               if (copy_from_user
+                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               break;
+       case VIAFB_SET_PANEL_SIZE:
+               if (copy_from_user
+                   (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+                       return -EFAULT;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void viafb_fillrect(struct fb_info *info,
+       const struct fb_fillrect *rect)
+{
+       u32 col = 0, rop = 0;
+       int pitch;
+
+       if (!viafb_accel)
+               return cfb_fillrect(info, rect);
+
+       if (!rect->width || !rect->height)
+               return;
+
+       switch (rect->rop) {
+       case ROP_XOR:
+               rop = 0x5A;
+               break;
+       case ROP_COPY:
+       default:
+               rop = 0xF0;
+               break;
+       }
+
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               col = rect->color;
+               break;
+       case 16:
+               col = ((u32 *) (info->pseudo_palette))[rect->color];
+               break;
+       case 32:
+               col = ((u32 *) (info->pseudo_palette))[rect->color];
+               break;
+       }
+
+       /* BitBlt Source Address */
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
+       /* Source Base Address */
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+       /* Destination Base Address */
+       writel(((unsigned long) (info->screen_base) -
+                  (unsigned long) viafb_FB_MM) >> 3,
+                  viaparinfo->io_virt + VIA_REG_DSTBASE);
+       /* Pitch */
+       pitch = (info->var.xres_virtual + 7) & ~7;
+       writel(VIA_PITCH_ENABLE |
+                  (((pitch *
+                     info->var.bits_per_pixel >> 3) >> 3) |
+                     (((pitch * info->
+                     var.bits_per_pixel >> 3) >> 3) << 16)),
+                     viaparinfo->io_virt + VIA_REG_PITCH);
+       /* BitBlt Destination Address */
+       writel(((rect->dy << 16) | rect->dx),
+               viaparinfo->io_virt + VIA_REG_DSTPOS);
+       /* Dimension: width & height */
+       writel((((rect->height - 1) << 16) | (rect->width - 1)),
+               viaparinfo->io_virt + VIA_REG_DIMENSION);
+       /* Forground color or Destination color */
+       writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
+       /* GE Command */
+       writel((0x01 | 0x2000 | (rop << 24)),
+               viaparinfo->io_virt + VIA_REG_GECMD);
+
+}
+
+static void viafb_copyarea(struct fb_info *info,
+       const struct fb_copyarea *area)
+{
+       u32 dy = area->dy, sy = area->sy, direction = 0x0;
+       u32 sx = area->sx, dx = area->dx, width = area->width;
+       int pitch;
+
+       DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n");
+
+       if (!viafb_accel)
+               return cfb_copyarea(info, area);
+
+       if (!area->width || !area->height)
+               return;
+
+       if (sy < dy) {
+               dy += area->height - 1;
+               sy += area->height - 1;
+               direction |= 0x4000;
+       }
+
+       if (sx < dx) {
+               dx += width - 1;
+               sx += width - 1;
+               direction |= 0x8000;
+       }
+
+       /* Source Base Address */
+       writel(((unsigned long) (info->screen_base) -
+                  (unsigned long) viafb_FB_MM) >> 3,
+                  viaparinfo->io_virt + VIA_REG_SRCBASE);
+       /* Destination Base Address */
+       writel(((unsigned long) (info->screen_base) -
+                  (unsigned long) viafb_FB_MM) >> 3,
+                  viaparinfo->io_virt + VIA_REG_DSTBASE);
+       /* Pitch */
+       pitch = (info->var.xres_virtual + 7) & ~7;
+       /* VIA_PITCH_ENABLE can be omitted now. */
+       writel(VIA_PITCH_ENABLE |
+                  (((pitch *
+                     info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
+                                                               info->var.
+                                                               bits_per_pixel
+                                                               >> 3) >> 3)
+                                                             << 16)),
+                               viaparinfo->io_virt + VIA_REG_PITCH);
+       /* BitBlt Source Address */
+       writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS);
+       /* BitBlt Destination Address */
+       writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS);
+       /* Dimension: width & height */
+       writel((((area->height - 1) << 16) | (area->width - 1)),
+                  viaparinfo->io_virt + VIA_REG_DIMENSION);
+       /* GE Command */
+       writel((0x01 | direction | (0xCC << 24)),
+               viaparinfo->io_virt + VIA_REG_GECMD);
+
+}
+
+static void viafb_imageblit(struct fb_info *info,
+       const struct fb_image *image)
+{
+       u32 size, bg_col = 0, fg_col = 0, *udata;
+       int i;
+       int pitch;
+
+       if (!viafb_accel)
+               return cfb_imageblit(info, image);
+
+       udata = (u32 *) image->data;
+
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               bg_col = image->bg_color;
+               fg_col = image->fg_color;
+               break;
+       case 16:
+               bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];
+               fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
+               break;
+       case 32:
+               bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];
+               fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
+               break;
+       }
+       size = image->width * image->height;
+
+       /* Source Base Address */
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+       /* Destination Base Address */
+       writel(((unsigned long) (info->screen_base) -
+                  (unsigned long) viafb_FB_MM) >> 3,
+                  viaparinfo->io_virt + VIA_REG_DSTBASE);
+       /* Pitch */
+       pitch = (info->var.xres_virtual + 7) & ~7;
+       writel(VIA_PITCH_ENABLE |
+                  (((pitch *
+                     info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
+                                                               info->var.
+                                                               bits_per_pixel
+                                                               >> 3) >> 3)
+                                                             << 16)),
+                               viaparinfo->io_virt + VIA_REG_PITCH);
+       /* BitBlt Source Address */
+       writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
+       /* BitBlt Destination Address */
+       writel(((image->dy << 16) | image->dx),
+               viaparinfo->io_virt + VIA_REG_DSTPOS);
+       /* Dimension: width & height */
+       writel((((image->height - 1) << 16) | (image->width - 1)),
+                  viaparinfo->io_virt + VIA_REG_DIMENSION);
+       /* fb color */
+       writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
+       /* bg color */
+       writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR);
+       /* GE Command */
+       writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD);
+
+       for (i = 0; i < size / 4; i++) {
+               writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE);
+               udata++;
+       }
+
+}
+
+static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+       u8 data[CURSOR_SIZE / 8];
+       u32 data_bak[CURSOR_SIZE / 32];
+       u32 temp, xx, yy, bg_col = 0, fg_col = 0;
+       int size, i, j = 0;
+       static int hw_cursor;
+       struct viafb_par *p_viafb_par;
+
+       if (viafb_accel)
+               hw_cursor = 1;
+
+       if (!viafb_accel) {
+               if (hw_cursor) {
+                       viafb_show_hw_cursor(info, HW_Cursor_OFF);
+                       hw_cursor = 0;
+               }
+               return -ENODEV;
+       }
+
+       if ((((struct viafb_par *)(info->par))->iga_path == IGA2)
+           && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
+               return -ENODEV;
+
+       /* When duoview and using lcd , use soft cursor */
+       if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview)
+               return -ENODEV;
+
+       viafb_show_hw_cursor(info, HW_Cursor_OFF);
+       viacursor = *cursor;
+
+       if (cursor->set & FB_CUR_SETHOT) {
+               viacursor.hot = cursor->hot;
+               temp = ((viacursor.hot.x) << 16) + viacursor.hot.y;
+               writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
+       }
+
+       if (cursor->set & FB_CUR_SETPOS) {
+               viacursor.image.dx = cursor->image.dx;
+               viacursor.image.dy = cursor->image.dy;
+               yy = cursor->image.dy - info->var.yoffset;
+               xx = cursor->image.dx - info->var.xoffset;
+               temp = yy & 0xFFFF;
+               temp |= (xx << 16);
+               writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
+       }
+
+       if (cursor->set & FB_CUR_SETSIZE) {
+               temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+
+               if ((cursor->image.width <= 32)
+                   && (cursor->image.height <= 32)) {
+                       MAX_CURS = 32;
+                       temp |= 0x2;
+               } else if ((cursor->image.width <= 64)
+                          && (cursor->image.height <= 64)) {
+                       MAX_CURS = 64;
+                       temp &= 0xFFFFFFFD;
+               } else {
+                       DEBUG_MSG(KERN_INFO
+                       "The cursor image is biger than 64x64 bits...\n");
+                       return -ENXIO;
+               }
+               writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+
+               viacursor.image.height = cursor->image.height;
+               viacursor.image.width = cursor->image.width;
+       }
+
+       if (cursor->set & FB_CUR_SETCMAP) {
+               viacursor.image.fg_color = cursor->image.fg_color;
+               viacursor.image.bg_color = cursor->image.bg_color;
+
+               switch (info->var.bits_per_pixel) {
+               case 8:
+               case 16:
+               case 32:
+                       bg_col =
+                           (0xFF << 24) |
+                           (((info->cmap.red)[viacursor.image.bg_color] &
+                           0xFF00) << 8) |
+                           ((info->cmap.green)[viacursor.image.bg_color] &
+                           0xFF00) |
+                           (((info->cmap.blue)[viacursor.image.bg_color] &
+                           0xFF00) >> 8);
+                       fg_col =
+                           (0xFF << 24) |
+                           (((info->cmap.red)[viacursor.image.fg_color] &
+                           0xFF00) << 8) |
+                           ((info->cmap.green)[viacursor.image.fg_color] &
+                           0xFF00) |
+                           (((info->cmap.blue)[viacursor.image.fg_color] &
+                           0xFF00) >> 8);
+                       break;
+               default:
+                       return 0;
+               }
+
+               /* This is indeed a patch for VT3324/VT3353 */
+               if (!info->par)
+                       return 0;
+               p_viafb_par = (struct viafb_par *)info->par;
+
+               if ((p_viafb_par->chip_info->gfx_chip_name ==
+                       UNICHROME_CX700) ||
+                       ((p_viafb_par->chip_info->gfx_chip_name ==
+                       UNICHROME_VX800))) {
+                       bg_col =
+                           (((info->cmap.red)[viacursor.image.bg_color] &
+                           0xFFC0) << 14) |
+                           (((info->cmap.green)[viacursor.image.bg_color] &
+                           0xFFC0) << 4) |
+                           (((info->cmap.blue)[viacursor.image.bg_color] &
+                           0xFFC0) >> 6);
+                       fg_col =
+                           (((info->cmap.red)[viacursor.image.fg_color] &
+                           0xFFC0) << 14) |
+                           (((info->cmap.green)[viacursor.image.fg_color] &
+                           0xFFC0) << 4) |
+                           (((info->cmap.blue)[viacursor.image.fg_color] &
+                           0xFFC0) >> 6);
+               }
+
+               writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
+               writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
+       }
+
+       if (cursor->set & FB_CUR_SETSHAPE) {
+               size =
+                   ((viacursor.image.width + 7) >> 3) *
+                   viacursor.image.height;
+
+               if (MAX_CURS == 32) {
+                       for (i = 0; i < (CURSOR_SIZE / 32); i++) {
+                               data_bak[i] = 0x0;
+                               data_bak[i + 1] = 0xFFFFFFFF;
+                               i += 1;
+                       }
+               } else if (MAX_CURS == 64) {
+                       for (i = 0; i < (CURSOR_SIZE / 32); i++) {
+                               data_bak[i] = 0x0;
+                               data_bak[i + 1] = 0x0;
+                               data_bak[i + 2] = 0xFFFFFFFF;
+                               data_bak[i + 3] = 0xFFFFFFFF;
+                               i += 3;
+                       }
+               }
+
+               switch (viacursor.rop) {
+               case ROP_XOR:
+                       for (i = 0; i < size; i++)
+                               data[i] = viacursor.mask[i];
+                       break;
+               case ROP_COPY:
+
+                       for (i = 0; i < size; i++)
+                               data[i] = viacursor.mask[i];
+                       break;
+               default:
+                       break;
+               }
+
+               if (MAX_CURS == 32) {
+                       for (i = 0; i < size; i++) {
+                               data_bak[j] = (u32) data[i];
+                               data_bak[j + 1] = ~data_bak[j];
+                               j += 2;
+                       }
+               } else if (MAX_CURS == 64) {
+                       for (i = 0; i < size; i++) {
+                               data_bak[j] = (u32) data[i];
+                               data_bak[j + 1] = 0x0;
+                               data_bak[j + 2] = ~data_bak[j];
+                               data_bak[j + 3] = ~data_bak[j + 1];
+                               j += 4;
+                       }
+               }
+
+               memcpy(((struct viafb_par *)(info->par))->fbmem_virt +
+                      ((struct viafb_par *)(info->par))->cursor_start,
+                      data_bak, CURSOR_SIZE);
+       }
+
+       if (viacursor.enable)
+               viafb_show_hw_cursor(info, HW_Cursor_ON);
+
+       return 0;
+}
+
+static int viafb_sync(struct fb_info *info)
+{
+       if (viafb_accel)
+               viafb_wait_engine_idle();
+       return 0;
+}
+
+int viafb_get_mode_index(int hres, int vres, int flag)
+{
+       u32 i;
+       DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
+
+       for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++)
+               if (viafb_modentry[i].xres == hres &&
+                       viafb_modentry[i].yres == vres)
+                       break;
+
+       viafb_resMode = viafb_modentry[i].mode_index;
+       if (flag)
+               viafb_mode1 = viafb_modentry[i].mode_res;
+       else
+               viafb_mode = viafb_modentry[i].mode_res;
+
+       return viafb_resMode;
+}
+
+static void check_available_device_to_enable(int device_id)
+{
+       int device_num = 0;
+
+       /* Initialize: */
+       viafb_CRT_ON = STATE_OFF;
+       viafb_DVI_ON = STATE_OFF;
+       viafb_LCD_ON = STATE_OFF;
+       viafb_LCD2_ON = STATE_OFF;
+       viafb_DeviceStatus = None_Device;
+
+       if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+               viafb_CRT_ON = STATE_ON;
+               device_num++;
+               viafb_DeviceStatus |= CRT_Device;
+       }
+
+       if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+               viafb_DVI_ON = STATE_ON;
+               device_num++;
+               viafb_DeviceStatus |= DVI_Device;
+       }
+
+       if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+               viafb_LCD_ON = STATE_ON;
+               device_num++;
+               viafb_DeviceStatus |= LCD_Device;
+       }
+
+       if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+               viafb_LCD2_ON = STATE_ON;
+               device_num++;
+               viafb_DeviceStatus |= LCD2_Device;
+       }
+
+       if (viafb_DeviceStatus == None_Device) {
+               /* Use CRT as default active device: */
+               viafb_CRT_ON = STATE_ON;
+               viafb_DeviceStatus = CRT_Device;
+       }
+       DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
+}
+
+static void viafb_set_device(struct device_t active_dev)
+{
+       /* Check available device to enable: */
+       int device_id = None_Device;
+       if (active_dev.crt)
+               device_id |= CRT_Device;
+       if (active_dev.dvi)
+               device_id |= DVI_Device;
+       if (active_dev.lcd)
+               device_id |= LCD_Device;
+
+       check_available_device_to_enable(device_id);
+
+       /* Check property of LCD: */
+       if (viafb_LCD_ON) {
+               if (active_dev.lcd_dsp_cent) {
+                       viaparinfo->lvds_setting_info->display_method =
+                               viafb_lcd_dsp_method = LCD_CENTERING;
+               } else {
+                       viaparinfo->lvds_setting_info->display_method =
+                               viafb_lcd_dsp_method = LCD_EXPANDSION;
+               }
+
+               if (active_dev.lcd_mode == LCD_SPWG) {
+                       viaparinfo->lvds_setting_info->lcd_mode =
+                               viafb_lcd_mode = LCD_SPWG;
+               } else {
+                       viaparinfo->lvds_setting_info->lcd_mode =
+                               viafb_lcd_mode = LCD_OPENLDI;
+               }
+
+               if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
+                       viafb_lcd_panel_id = active_dev.lcd_panel_id;
+                       viafb_init_lcd_size();
+               }
+       }
+
+       /* Check property of mode: */
+       if (!active_dev.xres1)
+               viafb_second_xres = 640;
+       else
+               viafb_second_xres = active_dev.xres1;
+       if (!active_dev.yres1)
+               viafb_second_yres = 480;
+       else
+               viafb_second_yres = active_dev.yres1;
+       if (active_dev.bpp != 0)
+               viafb_bpp = active_dev.bpp;
+       if (active_dev.bpp1 != 0)
+               viafb_bpp1 = active_dev.bpp1;
+       if (active_dev.refresh != 0)
+               viafb_refresh = active_dev.refresh;
+       if (active_dev.refresh1 != 0)
+               viafb_refresh1 = active_dev.refresh1;
+       if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
+               viafb_SAMM_ON = active_dev.samm;
+       viafb_primary_dev = active_dev.primary_dev;
+
+       viafb_set_start_addr();
+       viafb_set_iga_path();
+}
+
+static void viafb_set_video_device(u32 video_dev_info)
+{
+       viaparinfo->video_on_crt = STATE_OFF;
+       viaparinfo->video_on_dvi = STATE_OFF;
+       viaparinfo->video_on_lcd = STATE_OFF;
+
+       /* Check available device to enable: */
+       if ((video_dev_info & CRT_Device) == CRT_Device)
+               viaparinfo->video_on_crt = STATE_ON;
+       else if ((video_dev_info & DVI_Device) == DVI_Device)
+               viaparinfo->video_on_dvi = STATE_ON;
+       else if ((video_dev_info & LCD_Device) == LCD_Device)
+               viaparinfo->video_on_lcd = STATE_ON;
+}
+
+static void viafb_get_video_device(u32 *video_dev_info)
+{
+       *video_dev_info = None_Device;
+       if (viaparinfo->video_on_crt == STATE_ON)
+               *video_dev_info |= CRT_Device;
+       else if (viaparinfo->video_on_dvi == STATE_ON)
+               *video_dev_info |= DVI_Device;
+       else if (viaparinfo->video_on_lcd == STATE_ON)
+               *video_dev_info |= LCD_Device;
+}
+
+static int get_primary_device(void)
+{
+       int primary_device = 0;
+       /* Rule: device on iga1 path are the primary device. */
+       if (viafb_SAMM_ON) {
+               if (viafb_CRT_ON) {
+                       if (viaparinfo->crt_setting_info->iga_path == IGA1) {
+                               DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n",
+                                       viaparinfo->
+                                       crt_setting_info->iga_path);
+                               primary_device = CRT_Device;
+                       }
+               }
+               if (viafb_DVI_ON) {
+                       if (viaparinfo->tmds_setting_info->iga_path == IGA1) {
+                               DEBUG_MSG(KERN_INFO "DVI IGA Path:%d\n",
+                                       viaparinfo->
+                                       tmds_setting_info->iga_path);
+                               primary_device = DVI_Device;
+                       }
+               }
+               if (viafb_LCD_ON) {
+                       if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
+                               DEBUG_MSG(KERN_INFO "LCD IGA Path:%d\n",
+                                       viaparinfo->
+                                       lvds_setting_info->iga_path);
+                               primary_device = LCD_Device;
+                       }
+               }
+               if (viafb_LCD2_ON) {
+                       if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
+                               DEBUG_MSG(KERN_INFO "LCD2 IGA Path:%d\n",
+                                       viaparinfo->
+                                       lvds_setting_info2->iga_path);
+                               primary_device = LCD2_Device;
+                       }
+               }
+       }
+       return primary_device;
+}
+
+static u8 is_duoview(void)
+{
+       if (0 == viafb_SAMM_ON) {
+               if (viafb_LCD_ON + viafb_LCD2_ON +
+                       viafb_DVI_ON + viafb_CRT_ON == 2)
+                       return true;
+               return false;
+       } else {
+               return false;
+       }
+}
+
+static void apply_second_mode_setting(struct fb_var_screeninfo
+       *sec_var)
+{
+       u32 htotal, vtotal, long_refresh;
+
+       htotal = sec_var->xres + sec_var->left_margin +
+               sec_var->right_margin + sec_var->hsync_len;
+       vtotal = sec_var->yres + sec_var->upper_margin +
+               sec_var->lower_margin + sec_var->vsync_len;
+       if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
+               /*Is 32 bytes alignment? */
+               /*32 pixel alignment */
+               sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
+       }
+
+       htotal = sec_var->xres + sec_var->left_margin +
+               sec_var->right_margin + sec_var->hsync_len;
+       vtotal = sec_var->yres + sec_var->upper_margin +
+               sec_var->lower_margin + sec_var->vsync_len;
+       long_refresh = 1000000000UL / sec_var->pixclock * 1000;
+       long_refresh /= (htotal * vtotal);
+
+       viafb_second_xres = sec_var->xres;
+       viafb_second_yres = sec_var->yres;
+       viafb_second_virtual_xres = sec_var->xres_virtual;
+       viafb_second_virtual_yres = sec_var->yres_virtual;
+       viafb_bpp1 = sec_var->bits_per_pixel;
+       viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
+               long_refresh);
+}
+
+static int apply_device_setting(struct viafb_ioctl_setting setting_info,
+       struct fb_info *info)
+{
+       int need_set_mode = 0;
+       DEBUG_MSG(KERN_INFO "apply_device_setting\n");
+
+       if (setting_info.device_flag) {
+               need_set_mode = 1;
+               check_available_device_to_enable(setting_info.device_status);
+       }
+
+       /* Unlock LCD's operation according to LCD flag
+          and check if the setting value is valid. */
+       /* If the value is valid, apply the new setting value to the device. */
+       if (viafb_LCD_ON) {
+               if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
+                       need_set_mode = 1;
+                       if (setting_info.lcd_attributes.display_center) {
+                               /* Centering */
+                               viaparinfo->lvds_setting_info->display_method =
+                                   LCD_CENTERING;
+                               viafb_lcd_dsp_method = LCD_CENTERING;
+                               viaparinfo->lvds_setting_info2->display_method =
+                                   viafb_lcd_dsp_method = LCD_CENTERING;
+                       } else {
+                               /* expandsion */
+                               viaparinfo->lvds_setting_info->display_method =
+                                   LCD_EXPANDSION;
+                               viafb_lcd_dsp_method = LCD_EXPANDSION;
+                               viaparinfo->lvds_setting_info2->display_method =
+                                   LCD_EXPANDSION;
+                               viafb_lcd_dsp_method = LCD_EXPANDSION;
+                       }
+               }
+
+               if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
+                       need_set_mode = 1;
+                       if (setting_info.lcd_attributes.lcd_mode ==
+                               LCD_SPWG) {
+                               viaparinfo->lvds_setting_info->lcd_mode =
+                                       viafb_lcd_mode = LCD_SPWG;
+                       } else {
+                               viaparinfo->lvds_setting_info->lcd_mode =
+                                       viafb_lcd_mode = LCD_OPENLDI;
+                       }
+                       viaparinfo->lvds_setting_info2->lcd_mode =
+                           viaparinfo->lvds_setting_info->lcd_mode;
+               }
+
+               if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
+                       need_set_mode = 1;
+                       if (setting_info.lcd_attributes.panel_id <=
+                           LCD_PANEL_ID_MAXIMUM) {
+                               viafb_lcd_panel_id =
+                                   setting_info.lcd_attributes.panel_id;
+                               viafb_init_lcd_size();
+                       }
+               }
+       }
+
+       if (0 != (setting_info.samm_status & OP_SAMM)) {
+               setting_info.samm_status =
+                   setting_info.samm_status & (~OP_SAMM);
+               if (setting_info.samm_status == 0
+                   || setting_info.samm_status == 1) {
+                       viafb_SAMM_ON = setting_info.samm_status;
+
+                       if (viafb_SAMM_ON)
+                               viafb_primary_dev = setting_info.primary_device;
+
+                       viafb_set_start_addr();
+                       viafb_set_iga_path();
+               }
+               need_set_mode = 1;
+       }
+
+       viaparinfo->duoview = is_duoview();
+
+       if (!need_set_mode) {
+               ;
+       } else {
+               viafb_set_iga_path();
+               viafb_set_par(info);
+       }
+       return true;
+}
+
+static void retrieve_device_setting(struct viafb_ioctl_setting
+       *setting_info)
+{
+
+       /* get device status */
+       if (viafb_CRT_ON == 1)
+               setting_info->device_status = CRT_Device;
+       if (viafb_DVI_ON == 1)
+               setting_info->device_status |= DVI_Device;
+       if (viafb_LCD_ON == 1)
+               setting_info->device_status |= LCD_Device;
+       if (viafb_LCD2_ON == 1)
+               setting_info->device_status |= LCD2_Device;
+       if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) {
+               setting_info->video_device_status =
+                       viaparinfo->crt_setting_info->iga_path;
+       } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) {
+               setting_info->video_device_status =
+                       viaparinfo->tmds_setting_info->iga_path;
+       } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) {
+               setting_info->video_device_status =
+                       viaparinfo->lvds_setting_info->iga_path;
+       } else {
+               setting_info->video_device_status = 0;
+       }
+
+       setting_info->samm_status = viafb_SAMM_ON;
+       setting_info->primary_device = get_primary_device();
+
+       setting_info->first_dev_bpp = viafb_bpp;
+       setting_info->second_dev_bpp = viafb_bpp1;
+
+       setting_info->first_dev_refresh = viafb_refresh;
+       setting_info->second_dev_refresh = viafb_refresh1;
+
+       setting_info->first_dev_hor_res = viafb_hotplug_Xres;
+       setting_info->first_dev_ver_res = viafb_hotplug_Yres;
+       setting_info->second_dev_hor_res = viafb_second_xres;
+       setting_info->second_dev_ver_res = viafb_second_yres;
+
+       /* Get lcd attributes */
+       setting_info->lcd_attributes.display_center = viafb_lcd_dsp_method;
+       setting_info->lcd_attributes.panel_id = viafb_lcd_panel_id;
+       setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
+}
+
+static void parse_active_dev(void)
+{
+       viafb_CRT_ON = STATE_OFF;
+       viafb_DVI_ON = STATE_OFF;
+       viafb_LCD_ON = STATE_OFF;
+       viafb_LCD2_ON = STATE_OFF;
+       /* 1. Modify the active status of devices. */
+       /* 2. Keep the order of devices, so we can set corresponding
+          IGA path to devices in SAMM case. */
+       /*    Note: The previous of active_dev is primary device,
+          and the following is secondary device. */
+       if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) {
+               /* CRT+DVI */
+               viafb_CRT_ON = STATE_ON;
+               viafb_DVI_ON = STATE_ON;
+               viafb_primary_dev = CRT_Device;
+       } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) {
+               /* DVI+CRT */
+               viafb_CRT_ON = STATE_ON;
+               viafb_DVI_ON = STATE_ON;
+               viafb_primary_dev = DVI_Device;
+       } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) {
+               /* CRT+LCD */
+               viafb_CRT_ON = STATE_ON;
+               viafb_LCD_ON = STATE_ON;
+               viafb_primary_dev = CRT_Device;
+       } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) {
+               /* LCD+CRT */
+               viafb_CRT_ON = STATE_ON;
+               viafb_LCD_ON = STATE_ON;
+               viafb_primary_dev = LCD_Device;
+       } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) {
+               /* DVI+LCD */
+               viafb_DVI_ON = STATE_ON;
+               viafb_LCD_ON = STATE_ON;
+               viafb_primary_dev = DVI_Device;
+       } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) {
+               /* LCD+DVI */
+               viafb_DVI_ON = STATE_ON;
+               viafb_LCD_ON = STATE_ON;
+               viafb_primary_dev = LCD_Device;
+       } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) {
+               viafb_LCD_ON = STATE_ON;
+               viafb_LCD2_ON = STATE_ON;
+               viafb_primary_dev = LCD_Device;
+       } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) {
+               viafb_LCD_ON = STATE_ON;
+               viafb_LCD2_ON = STATE_ON;
+               viafb_primary_dev = LCD2_Device;
+       } else if (!strncmp(viafb_active_dev, "CRT", 3)) {
+               /* CRT only */
+               viafb_CRT_ON = STATE_ON;
+               viafb_SAMM_ON = STATE_OFF;
+       } else if (!strncmp(viafb_active_dev, "DVI", 3)) {
+               /* DVI only */
+               viafb_DVI_ON = STATE_ON;
+               viafb_SAMM_ON = STATE_OFF;
+       } else if (!strncmp(viafb_active_dev, "LCD", 3)) {
+               /* LCD only */
+               viafb_LCD_ON = STATE_ON;
+               viafb_SAMM_ON = STATE_OFF;
+       } else {
+               viafb_CRT_ON = STATE_ON;
+               viafb_SAMM_ON = STATE_OFF;
+       }
+       viaparinfo->duoview = is_duoview();
+}
+
+static void parse_video_dev(void)
+{
+       viaparinfo->video_on_crt = STATE_OFF;
+       viaparinfo->video_on_dvi = STATE_OFF;
+       viaparinfo->video_on_lcd = STATE_OFF;
+
+       if (!strncmp(viafb_video_dev, "CRT", 3)) {
+               /* Video on CRT */
+               viaparinfo->video_on_crt = STATE_ON;
+       } else if (!strncmp(viafb_video_dev, "DVI", 3)) {
+               /* Video on DVI */
+               viaparinfo->video_on_dvi = STATE_ON;
+       } else if (!strncmp(viafb_video_dev, "LCD", 3)) {
+               /* Video on LCD */
+               viaparinfo->video_on_lcd = STATE_ON;
+       }
+}
+
+static int parse_port(char *opt_str, int *output_interface)
+{
+       if (!strncmp(opt_str, "DVP0", 4))
+               *output_interface = INTERFACE_DVP0;
+       else if (!strncmp(opt_str, "DVP1", 4))
+               *output_interface = INTERFACE_DVP1;
+       else if (!strncmp(opt_str, "DFP_HIGHLOW", 11))
+               *output_interface = INTERFACE_DFP;
+       else if (!strncmp(opt_str, "DFP_HIGH", 8))
+               *output_interface = INTERFACE_DFP_HIGH;
+       else if (!strncmp(opt_str, "DFP_LOW", 7))
+               *output_interface = INTERFACE_DFP_LOW;
+       else
+               *output_interface = INTERFACE_NONE;
+       return 0;
+}
+
+static void parse_lcd_port(void)
+{
+       parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info.
+               output_interface);
+       /*Initialize to avoid unexpected behavior */
+       viaparinfo->chip_info->lvds_chip_info2.output_interface =
+       INTERFACE_NONE;
+
+       DEBUG_MSG(KERN_INFO "parse_lcd_port: viafb_lcd_port:%s,interface:%d\n",
+                 viafb_lcd_port, viaparinfo->chip_info->lvds_chip_info.
+                 output_interface);
+}
+
+static void parse_dvi_port(void)
+{
+       parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info.
+               output_interface);
+
+       DEBUG_MSG(KERN_INFO "parse_dvi_port: viafb_dvi_port:%s,interface:%d\n",
+                 viafb_dvi_port, viaparinfo->chip_info->tmds_chip_info.
+                 output_interface);
+}
+
+/*
+ * The proc filesystem read/write function, a simple proc implement to
+ * get/set the value of DPA  DVP0,   DVP0DataDriving,  DVP0ClockDriving, DVP1,
+ * DVP1Driving, DFPHigh, DFPLow CR96,   SR2A[5], SR1B[1], SR2A[4], SR1E[2],
+ * CR9B,    SR65,    CR97,    CR99
+ */
+static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset,
+int count, int *eof, void *data)
+{
+       int len = 0;
+       u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0;
+       dvp0_data_dri =
+           (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 |
+           (viafb_read_reg(VIASR, SR1B) & BIT1) >> 1;
+       dvp0_clk_dri =
+           (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 |
+           (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2;
+       dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f;
+       len +=
+           sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri);
+       *eof = 1;               /*Inform kernel end of data */
+       return len;
+}
+static int viafb_dvp0_proc_write(struct file *file,
+       const char __user *buffer, unsigned long count, void *data)
+{
+       char buf[20], *value, *pbuf;
+       u8 reg_val = 0;
+       unsigned long length, i;
+       if (count < 1)
+               return -EINVAL;
+       length = count > 20 ? 20 : count;
+       if (copy_from_user(&buf[0], buffer, length))
+               return -EFAULT;
+       buf[length - 1] = '\0'; /*Ensure end string */
+       pbuf = &buf[0];
+       for (i = 0; i < 3; i++) {
+               value = strsep(&pbuf, " ");
+               if (value != NULL) {
+                       strict_strtoul(value, 0, (unsigned long *)&reg_val);
+                       DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i,
+                                 reg_val);
+                       switch (i) {
+                       case 0:
+                               viafb_write_reg_mask(CR96, VIACR,
+                                       reg_val, 0x0f);
+                               break;
+                       case 1:
+                               viafb_write_reg_mask(SR2A, VIASR,
+                                       reg_val << 4, BIT5);
+                               viafb_write_reg_mask(SR1B, VIASR,
+                                       reg_val << 1, BIT1);
+                               break;
+                       case 2:
+                               viafb_write_reg_mask(SR2A, VIASR,
+                                       reg_val << 3, BIT4);
+                               viafb_write_reg_mask(SR1E, VIASR,
+                                       reg_val << 2, BIT2);
+                               break;
+                       default:
+                               break;
+                       }
+               } else {
+                       break;
+               }
+       }
+       return count;
+}
+static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset,
+       int count, int *eof, void *data)
+{
+       int len = 0;
+       u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0;
+       dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f;
+       dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2;
+       dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03;
+       len +=
+           sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri);
+       *eof = 1;               /*Inform kernel end of data */
+       return len;
+}
+static int viafb_dvp1_proc_write(struct file *file,
+       const char __user *buffer, unsigned long count, void *data)
+{
+       char buf[20], *value, *pbuf;
+       u8 reg_val = 0;
+       unsigned long length, i;
+       if (count < 1)
+               return -EINVAL;
+       length = count > 20 ? 20 : count;
+       if (copy_from_user(&buf[0], buffer, length))
+               return -EFAULT;
+       buf[length - 1] = '\0'; /*Ensure end string */
+       pbuf = &buf[0];
+       for (i = 0; i < 3; i++) {
+               value = strsep(&pbuf, " ");
+               if (value != NULL) {
+                       strict_strtoul(value, 0, (unsigned long *)&reg_val);
+                       switch (i) {
+                       case 0:
+                               viafb_write_reg_mask(CR9B, VIACR,
+                                       reg_val, 0x0f);
+                               break;
+                       case 1:
+                               viafb_write_reg_mask(SR65, VIASR,
+                                       reg_val << 2, 0x0c);
+                               break;
+                       case 2:
+                               viafb_write_reg_mask(SR65, VIASR,
+                                       reg_val, 0x03);
+                               break;
+                       default:
+                               break;
+                       }
+               } else {
+                       break;
+               }
+       }
+       return count;
+}
+
+static int viafb_dfph_proc_read(char *buf, char **start, off_t offset,
+       int count, int *eof, void *data)
+{
+       int len = 0;
+       u8 dfp_high = 0;
+       dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f;
+       len += sprintf(buf + len, "%x\n", dfp_high);
+       *eof = 1;               /*Inform kernel end of data */
+       return len;
+}
+static int viafb_dfph_proc_write(struct file *file,
+       const char __user *buffer, unsigned long count, void *data)
+{
+       char buf[20];
+       u8 reg_val = 0;
+       unsigned long length;
+       if (count < 1)
+               return -EINVAL;
+       length = count > 20 ? 20 : count;
+       if (copy_from_user(&buf[0], buffer, length))
+               return -EFAULT;
+       buf[length - 1] = '\0'; /*Ensure end string */
+       strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
+       viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
+       return count;
+}
+static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset,
+       int count, int *eof, void *data)
+{
+       int len = 0;
+       u8 dfp_low = 0;
+       dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f;
+       len += sprintf(buf + len, "%x\n", dfp_low);
+       *eof = 1;               /*Inform kernel end of data */
+       return len;
+}
+static int viafb_dfpl_proc_write(struct file *file,
+       const char __user *buffer, unsigned long count, void *data)
+{
+       char buf[20];
+       u8 reg_val = 0;
+       unsigned long length;
+       if (count < 1)
+               return -EINVAL;
+       length = count > 20 ? 20 : count;
+       if (copy_from_user(&buf[0], buffer, length))
+               return -EFAULT;
+       buf[length - 1] = '\0'; /*Ensure end string */
+       strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
+       viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
+       return count;
+}
+static int viafb_vt1636_proc_read(char *buf, char **start,
+       off_t offset, int count, int *eof, void *data)
+{
+       int len = 0;
+       u8 vt1636_08 = 0, vt1636_09 = 0;
+       switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+       case VT1636_LVDS:
+               vt1636_08 =
+                   viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
+                   &viaparinfo->chip_info->lvds_chip_info, 0x08) & 0x0f;
+               vt1636_09 =
+                   viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
+                   &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f;
+               len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09);
+               break;
+       default:
+               break;
+       }
+       switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+       case VT1636_LVDS:
+               vt1636_08 =
+                   viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
+                       &viaparinfo->chip_info->lvds_chip_info2, 0x08) & 0x0f;
+               vt1636_09 =
+                   viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
+                       &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f;
+               len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09);
+               break;
+       default:
+               break;
+       }
+       *eof = 1;               /*Inform kernel end of data */
+       return len;
+}
+static int viafb_vt1636_proc_write(struct file *file,
+       const char __user *buffer, unsigned long count, void *data)
+{
+       char buf[30], *value, *pbuf;
+       struct IODATA reg_val;
+       unsigned long length, i;
+       if (count < 1)
+               return -EINVAL;
+       length = count > 30 ? 30 : count;
+       if (copy_from_user(&buf[0], buffer, length))
+               return -EFAULT;
+       buf[length - 1] = '\0'; /*Ensure end string */
+       pbuf = &buf[0];
+       switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+       case VT1636_LVDS:
+               for (i = 0; i < 2; i++) {
+                       value = strsep(&pbuf, " ");
+                       if (value != NULL) {
+                               strict_strtoul(value, 0,
+                                       (unsigned long *)&reg_val.Data);
+                               switch (i) {
+                               case 0:
+                                       reg_val.Index = 0x08;
+                                       reg_val.Mask = 0x0f;
+                                       viafb_gpio_i2c_write_mask_lvds
+                                           (viaparinfo->lvds_setting_info,
+                                           &viaparinfo->
+                                           chip_info->lvds_chip_info,
+                                            reg_val);
+                                       break;
+                               case 1:
+                                       reg_val.Index = 0x09;
+                                       reg_val.Mask = 0x1f;
+                                       viafb_gpio_i2c_write_mask_lvds
+                                           (viaparinfo->lvds_setting_info,
+                                           &viaparinfo->
+                                           chip_info->lvds_chip_info,
+                                            reg_val);
+                                       break;
+                               default:
+                                       break;
+                               }
+                       } else {
+                               break;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+       switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+       case VT1636_LVDS:
+               for (i = 0; i < 2; i++) {
+                       value = strsep(&pbuf, " ");
+                       if (value != NULL) {
+                               strict_strtoul(value, 0,
+                                       (unsigned long *)&reg_val.Data);
+                               switch (i) {
+                               case 0:
+                                       reg_val.Index = 0x08;
+                                       reg_val.Mask = 0x0f;
+                                       viafb_gpio_i2c_write_mask_lvds
+                                           (viaparinfo->lvds_setting_info2,
+                                           &viaparinfo->
+                                           chip_info->lvds_chip_info2,
+                                            reg_val);
+                                       break;
+                               case 1:
+                                       reg_val.Index = 0x09;
+                                       reg_val.Mask = 0x1f;
+                                       viafb_gpio_i2c_write_mask_lvds
+                                           (viaparinfo->lvds_setting_info2,
+                                           &viaparinfo->
+                                           chip_info->lvds_chip_info2,
+                                            reg_val);
+                                       break;
+                               default:
+                                       break;
+                               }
+                       } else {
+                               break;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+       return count;
+}
+
+static void viafb_init_proc(struct proc_dir_entry *viafb_entry)
+{
+       struct proc_dir_entry *entry;
+       viafb_entry = proc_mkdir("viafb", NULL);
+       if (viafb_entry) {
+               entry = create_proc_entry("dvp0", 0, viafb_entry);
+               if (entry) {
+                       entry->owner = THIS_MODULE;
+                       entry->read_proc = viafb_dvp0_proc_read;
+                       entry->write_proc = viafb_dvp0_proc_write;
+               }
+               entry = create_proc_entry("dvp1", 0, viafb_entry);
+               if (entry) {
+                       entry->owner = THIS_MODULE;
+                       entry->read_proc = viafb_dvp1_proc_read;
+                       entry->write_proc = viafb_dvp1_proc_write;
+               }
+               entry = create_proc_entry("dfph", 0, viafb_entry);
+               if (entry) {
+                       entry->owner = THIS_MODULE;
+                       entry->read_proc = viafb_dfph_proc_read;
+                       entry->write_proc = viafb_dfph_proc_write;
+               }
+               entry = create_proc_entry("dfpl", 0, viafb_entry);
+               if (entry) {
+                       entry->owner = THIS_MODULE;
+                       entry->read_proc = viafb_dfpl_proc_read;
+                       entry->write_proc = viafb_dfpl_proc_write;
+               }
+               if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info.
+                       lvds_chip_name || VT1636_LVDS ==
+                   viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+                       entry = create_proc_entry("vt1636", 0, viafb_entry);
+                       if (entry) {
+                               entry->owner = THIS_MODULE;
+                               entry->read_proc = viafb_vt1636_proc_read;
+                               entry->write_proc = viafb_vt1636_proc_write;
+                       }
+               }
+
+       }
+}
+static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
+{
+       /* no problem if it was not registered */
+       remove_proc_entry("dvp0", viafb_entry);/* parent dir */
+       remove_proc_entry("dvp1", viafb_entry);
+       remove_proc_entry("dfph", viafb_entry);
+       remove_proc_entry("dfpl", viafb_entry);
+       remove_proc_entry("vt1636", viafb_entry);
+       remove_proc_entry("vt1625", viafb_entry);
+}
+
+static int __devinit via_pci_probe(void)
+{
+       unsigned int default_xres, default_yres;
+       char *tmpc, *tmpm;
+       char *tmpc_sec, *tmpm_sec;
+       int vmode_index;
+       u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length;
+
+       DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
+
+       viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8);
+       tmds_length = ALIGN(sizeof(struct tmds_setting_information),
+               BITS_PER_LONG/8);
+       lvds_length = ALIGN(sizeof(struct lvds_setting_information),
+               BITS_PER_LONG/8);
+       crt_length = ALIGN(sizeof(struct lvds_setting_information),
+               BITS_PER_LONG/8);
+       chip_length = ALIGN(sizeof(struct chip_information), BITS_PER_LONG/8);
+
+       /* Allocate fb_info and ***_par here, also including some other needed
+        * variables
+       */
+       viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length +
+       tmds_length + crt_length + chip_length, NULL);
+       if (!viafbinfo) {
+               printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
+               return -ENODEV;
+       }
+
+       viaparinfo = (struct viafb_par *)viafbinfo->par;
+       viaparinfo->tmds_setting_info = (struct tmds_setting_information *)
+               ((unsigned long)viaparinfo + viafb_par_length);
+       viaparinfo->lvds_setting_info = (struct lvds_setting_information *)
+               ((unsigned long)viaparinfo->tmds_setting_info + tmds_length);
+       viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *)
+               ((unsigned long)viaparinfo->lvds_setting_info + lvds_length);
+       viaparinfo->crt_setting_info = (struct crt_setting_information *)
+               ((unsigned long)viaparinfo->lvds_setting_info2 + lvds_length);
+       viaparinfo->chip_info = (struct chip_information *)
+               ((unsigned long)viaparinfo->crt_setting_info + crt_length);
+
+       if (viafb_dual_fb)
+               viafb_SAMM_ON = 1;
+       parse_active_dev();
+       parse_video_dev();
+       parse_lcd_port();
+       parse_dvi_port();
+
+       /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
+       if (!viafb_SAMM_ON)
+               viafb_dual_fb = 0;
+
+       /* Set up I2C bus stuff */
+       viafb_create_i2c_bus(viaparinfo);
+
+       viafb_init_chip_info();
+       viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize);
+       viaparinfo->fbmem_free = viaparinfo->memsize;
+       viaparinfo->fbmem_used = 0;
+       viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem,
+               viaparinfo->memsize);
+       viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt;
+
+       if (!viaparinfo->fbmem_virt) {
+               printk(KERN_INFO "ioremap failed\n");
+               return -1;
+       }
+
+       viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len);
+       viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base,
+               viaparinfo->mmio_len);
+
+       viafbinfo->node = 0;
+       viafbinfo->fbops = &viafb_ops;
+       viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+       viafbinfo->pseudo_palette = pseudo_pal;
+       if (viafb_accel) {
+               viafb_init_accel();
+               viafb_init_2d_engine();
+               viafb_hw_cursor_init();
+       }
+
+       if (viafb_second_size && (viafb_second_size < 8)) {
+               viafb_second_offset = viaparinfo->fbmem_free -
+                       viafb_second_size * 1024 * 1024;
+       } else {
+               viafb_second_size = 8;
+               viafb_second_offset = viaparinfo->fbmem_free -
+                       viafb_second_size * 1024 * 1024;
+       }
+
+       viafb_FB_MM = viaparinfo->fbmem_virt;
+       tmpm = viafb_mode;
+       tmpc = strsep(&tmpm, "x");
+       strict_strtoul(tmpc, 0, (unsigned long *)&default_xres);
+       strict_strtoul(tmpm, 0, (unsigned long *)&default_yres);
+
+       vmode_index = viafb_get_mode_index(default_xres, default_yres, 0);
+       DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
+
+       if (viafb_SAMM_ON == 1) {
+               if (strcmp(viafb_mode, viafb_mode1)) {
+                       tmpm_sec = viafb_mode1;
+                       tmpc_sec = strsep(&tmpm_sec, "x");
+                       strict_strtoul(tmpc_sec, 0,
+                               (unsigned long *)&viafb_second_xres);
+                       strict_strtoul(tmpm_sec, 0,
+                               (unsigned long *)&viafb_second_yres);
+               } else {
+                       viafb_second_xres = default_xres;
+                       viafb_second_yres = default_yres;
+               }
+               if (0 == viafb_second_virtual_xres) {
+                       switch (viafb_second_xres) {
+                       case 1400:
+                               viafb_second_virtual_xres = 1408;
+                               break;
+                       default:
+                               viafb_second_virtual_xres = viafb_second_xres;
+                               break;
+                       }
+               }
+               if (0 == viafb_second_virtual_yres)
+                       viafb_second_virtual_yres = viafb_second_yres;
+       }
+
+       switch (viafb_bpp) {
+       case 0 ... 8:
+               viafb_bpp = 8;
+               break;
+       case 9 ... 16:
+               viafb_bpp = 16;
+               break;
+       case 17 ... 32:
+               viafb_bpp = 32;
+               break;
+       default:
+               viafb_bpp = 8;
+       }
+       default_var.xres = default_xres;
+       default_var.yres = default_yres;
+       switch (default_xres) {
+       case 1400:
+               default_var.xres_virtual = 1408;
+               break;
+       default:
+               default_var.xres_virtual = default_xres;
+               break;
+       }
+       default_var.yres_virtual = default_yres;
+       default_var.bits_per_pixel = viafb_bpp;
+       if (default_var.bits_per_pixel == 15)
+               default_var.bits_per_pixel = 16;
+       default_var.pixclock =
+           viafb_get_pixclock(default_xres, default_yres, viafb_refresh);
+       default_var.left_margin = (default_xres >> 3) & 0xf8;
+       default_var.right_margin = 32;
+       default_var.upper_margin = 16;
+       default_var.lower_margin = 4;
+       default_var.hsync_len = default_var.left_margin;
+       default_var.vsync_len = 4;
+       default_var.accel_flags = 0;
+
+       if (viafb_accel) {
+               viafbinfo->flags |=
+                   (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
+                    FBINFO_HWACCEL_IMAGEBLIT);
+               default_var.accel_flags |= FB_ACCELF_TEXT;
+       } else
+               viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
+
+       if (viafb_dual_fb) {
+               viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL);
+               if (!viafbinfo1) {
+                       printk(KERN_ERR
+                       "allocate the second framebuffer struct error\n");
+                       framebuffer_release(viafbinfo);
+                       return -ENOMEM;
+               }
+               viaparinfo1 = viafbinfo1->par;
+               memcpy(viaparinfo1, viaparinfo, viafb_par_length);
+               viaparinfo1->memsize = viaparinfo->memsize -
+                       viafb_second_offset;
+               viaparinfo->memsize = viafb_second_offset;
+               viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt +
+                       viafb_second_offset;
+               viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset;
+
+               viaparinfo1->fbmem_used = viaparinfo->fbmem_used;
+               viaparinfo1->fbmem_free = viaparinfo1->memsize -
+                       viaparinfo1->fbmem_used;
+               viaparinfo->fbmem_free = viaparinfo->memsize;
+               viaparinfo->fbmem_used = 0;
+               if (viafb_accel) {
+                       viaparinfo1->cursor_start =
+                           viaparinfo->cursor_start - viafb_second_offset;
+                       viaparinfo1->VQ_start = viaparinfo->VQ_start -
+                               viafb_second_offset;
+                       viaparinfo1->VQ_end = viaparinfo->VQ_end -
+                               viafb_second_offset;
+               }
+
+               memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info));
+               viafbinfo1->screen_base = viafbinfo->screen_base +
+                       viafb_second_offset;
+               viafbinfo1->fix.smem_start = viaparinfo1->fbmem;
+               viafbinfo1->fix.smem_len = viaparinfo1->fbmem_free;
+
+               default_var.xres = viafb_second_xres;
+               default_var.yres = viafb_second_yres;
+               default_var.xres_virtual = viafb_second_virtual_xres;
+               default_var.yres_virtual = viafb_second_virtual_yres;
+               if (viafb_bpp1 != viafb_bpp)
+                       viafb_bpp1 = viafb_bpp;
+               default_var.bits_per_pixel = viafb_bpp1;
+               default_var.pixclock =
+                   viafb_get_pixclock(viafb_second_xres, viafb_second_yres,
+                   viafb_refresh);
+               default_var.left_margin = (viafb_second_xres >> 3) & 0xf8;
+               default_var.right_margin = 32;
+               default_var.upper_margin = 16;
+               default_var.lower_margin = 4;
+               default_var.hsync_len = default_var.left_margin;
+               default_var.vsync_len = 4;
+
+               viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
+               viafb_check_var(&default_var, viafbinfo1);
+               viafbinfo1->var = default_var;
+               viafb_update_viafb_par(viafbinfo);
+               viafb_update_fix(&viafbinfo1->fix, viafbinfo1);
+       }
+
+       viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
+       viafb_check_var(&default_var, viafbinfo);
+       viafbinfo->var = default_var;
+       viafb_update_viafb_par(viafbinfo);
+       viafb_update_fix(&viafbinfo->fix, viafbinfo);
+       default_var.activate = FB_ACTIVATE_NOW;
+       fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
+
+       if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
+           && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) {
+               if (register_framebuffer(viafbinfo1) < 0)
+                       return -EINVAL;
+       }
+       if (register_framebuffer(viafbinfo) < 0)
+               return -EINVAL;
+
+       if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device)
+                       || (viaparinfo->chip_info->gfx_chip_name !=
+                       UNICHROME_CLE266))) {
+               if (register_framebuffer(viafbinfo1) < 0)
+                       return -EINVAL;
+       }
+       DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n",
+                 viafbinfo->node, viafbinfo->fix.id, default_var.xres,
+                 default_var.yres, default_var.bits_per_pixel);
+
+       viafb_init_proc(viaparinfo->proc_entry);
+       viafb_init_dac(IGA2);
+       return 0;
+}
+
+static void __devexit via_pci_remove(void)
+{
+       DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
+       fb_dealloc_cmap(&viafbinfo->cmap);
+       unregister_framebuffer(viafbinfo);
+       if (viafb_dual_fb)
+               unregister_framebuffer(viafbinfo1);
+       iounmap((void *)viaparinfo->fbmem_virt);
+       iounmap(viaparinfo->io_virt);
+
+       viafb_delete_i2c_buss(viaparinfo);
+
+       framebuffer_release(viafbinfo);
+       if (viafb_dual_fb)
+               framebuffer_release(viafbinfo1);
+
+       viafb_remove_proc(viaparinfo->proc_entry);
+}
+
+#ifndef MODULE
+static int __init viafb_setup(char *options)
+{
+       char *this_opt;
+       DEBUG_MSG(KERN_INFO "viafb_setup!\n");
+
+       if (!options || !*options)
+               return 0;
+
+       while ((this_opt = strsep(&options, ",")) != NULL) {
+               if (!*this_opt)
+                       continue;
+
+               if (!strncmp(this_opt, "viafb_mode1=", 12))
+                       viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL);
+               else if (!strncmp(this_opt, "viafb_mode=", 11))
+                       viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL);
+               else if (!strncmp(this_opt, "viafb_bpp1=", 11))
+                       strict_strtoul(this_opt + 11, 0,
+                               (unsigned long *)&viafb_bpp1);
+               else if (!strncmp(this_opt, "viafb_bpp=", 10))
+                       strict_strtoul(this_opt + 10, 0,
+                               (unsigned long *)&viafb_bpp);
+               else if (!strncmp(this_opt, "viafb_refresh1=", 15))
+                       strict_strtoul(this_opt + 15, 0,
+                               (unsigned long *)&viafb_refresh1);
+               else if (!strncmp(this_opt, "viafb_refresh=", 14))
+                       strict_strtoul(this_opt + 14, 0,
+                               (unsigned long *)&viafb_refresh);
+               else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21))
+                       strict_strtoul(this_opt + 21, 0,
+                               (unsigned long *)&viafb_lcd_dsp_method);
+               else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19))
+                       strict_strtoul(this_opt + 19, 0,
+                               (unsigned long *)&viafb_lcd_panel_id);
+               else if (!strncmp(this_opt, "viafb_accel=", 12))
+                       strict_strtoul(this_opt + 12, 0,
+                               (unsigned long *)&viafb_accel);
+               else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14))
+                       strict_strtoul(this_opt + 14, 0,
+                               (unsigned long *)&viafb_SAMM_ON);
+               else if (!strncmp(this_opt, "viafb_active_dev=", 17))
+                       viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL);
+               else if (!strncmp(this_opt,
+                       "viafb_display_hardware_layout=", 30))
+                       strict_strtoul(this_opt + 30, 0,
+                       (unsigned long *)&viafb_display_hardware_layout);
+               else if (!strncmp(this_opt, "viafb_second_size=", 18))
+                       strict_strtoul(this_opt + 18, 0,
+                               (unsigned long *)&viafb_second_size);
+               else if (!strncmp(this_opt,
+                       "viafb_platform_epia_dvi=", 24))
+                       strict_strtoul(this_opt + 24, 0,
+                               (unsigned long *)&viafb_platform_epia_dvi);
+               else if (!strncmp(this_opt,
+                       "viafb_device_lcd_dualedge=", 26))
+                       strict_strtoul(this_opt + 26, 0,
+                               (unsigned long *)&viafb_device_lcd_dualedge);
+               else if (!strncmp(this_opt, "viafb_bus_width=", 16))
+                       strict_strtoul(this_opt + 16, 0,
+                               (unsigned long *)&viafb_bus_width);
+               else if (!strncmp(this_opt, "viafb_lcd_mode=", 15))
+                       strict_strtoul(this_opt + 15, 0,
+                               (unsigned long *)&viafb_lcd_mode);
+               else if (!strncmp(this_opt, "viafb_video_dev=", 16))
+                       viafb_video_dev = kstrdup(this_opt + 16, GFP_KERNEL);
+               else if (!strncmp(this_opt, "viafb_lcd_port=", 15))
+                       viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL);
+               else if (!strncmp(this_opt, "viafb_dvi_port=", 15))
+                       viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL);
+       }
+       return 0;
+}
+#endif
+
+static int __init viafb_init(void)
+{
+#ifndef MODULE
+       char *option = NULL;
+       if (fb_get_options("viafb", &option))
+               return -ENODEV;
+       viafb_setup(option);
+#endif
+       printk(KERN_INFO
+       "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
+              VERSION_MAJOR, VERSION_MINOR);
+       return via_pci_probe();
+}
+
+static void __exit viafb_exit(void)
+{
+       DEBUG_MSG(KERN_INFO "viafb_exit!\n");
+       via_pci_remove();
+}
+
+static struct fb_ops viafb_ops = {
+       .owner = THIS_MODULE,
+       .fb_open = viafb_open,
+       .fb_release = viafb_release,
+       .fb_check_var = viafb_check_var,
+       .fb_set_par = viafb_set_par,
+       .fb_setcolreg = viafb_setcolreg,
+       .fb_pan_display = viafb_pan_display,
+       .fb_blank = viafb_blank,
+       .fb_fillrect = viafb_fillrect,
+       .fb_copyarea = viafb_copyarea,
+       .fb_imageblit = viafb_imageblit,
+       .fb_cursor = viafb_cursor,
+       .fb_ioctl = viafb_ioctl,
+       .fb_sync = viafb_sync,
+       .fb_setcmap = viafb_setcmap,
+};
+
+module_init(viafb_init);
+module_exit(viafb_exit);
+
+#ifdef MODULE
+module_param(viafb_memsize, int, 0);
+
+module_param(viafb_mode, charp, 0);
+MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)");
+
+module_param(viafb_mode1, charp, 0);
+MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)");
+
+module_param(viafb_bpp, int, 0);
+MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)");
+
+module_param(viafb_bpp1, int, 0);
+MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)");
+
+module_param(viafb_refresh, int, 0);
+MODULE_PARM_DESC(viafb_refresh,
+       "Set CRT viafb_refresh rate (default = 60)");
+
+module_param(viafb_refresh1, int, 0);
+MODULE_PARM_DESC(viafb_refresh1,
+       "Set CRT refresh rate (default = 60)");
+
+module_param(viafb_lcd_panel_id, int, 0);
+MODULE_PARM_DESC(viafb_lcd_panel_id,
+       "Set Flat Panel type(Default=1024x768)");
+
+module_param(viafb_lcd_dsp_method, int, 0);
+MODULE_PARM_DESC(viafb_lcd_dsp_method,
+       "Set Flat Panel display scaling method.(Default=Expandsion)");
+
+module_param(viafb_SAMM_ON, int, 0);
+MODULE_PARM_DESC(viafb_SAMM_ON,
+       "Turn on/off flag of SAMM(Default=OFF)");
+
+module_param(viafb_accel, int, 0);
+MODULE_PARM_DESC(viafb_accel,
+       "Set 2D Hardware Acceleration.(Default = OFF)");
+
+module_param(viafb_active_dev, charp, 0);
+MODULE_PARM_DESC(viafb_active_dev, "Specify active devices.");
+
+module_param(viafb_display_hardware_layout, int, 0);
+MODULE_PARM_DESC(viafb_display_hardware_layout,
+       "Display Hardware Layout (LCD Only, DVI Only...,etc)");
+
+module_param(viafb_second_size, int, 0);
+MODULE_PARM_DESC(viafb_second_size,
+       "Set secondary device memory size");
+
+module_param(viafb_dual_fb, int, 0);
+MODULE_PARM_DESC(viafb_dual_fb,
+       "Turn on/off flag of dual framebuffer devices.(Default = OFF)");
+
+module_param(viafb_platform_epia_dvi, int, 0);
+MODULE_PARM_DESC(viafb_platform_epia_dvi,
+       "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)");
+
+module_param(viafb_device_lcd_dualedge, int, 0);
+MODULE_PARM_DESC(viafb_device_lcd_dualedge,
+       "Turn on/off flag of dual edge panel.(Default = OFF)");
+
+module_param(viafb_bus_width, int, 0);
+MODULE_PARM_DESC(viafb_bus_width,
+       "Set bus width of panel.(Default = 12)");
+
+module_param(viafb_lcd_mode, int, 0);
+MODULE_PARM_DESC(viafb_lcd_mode,
+       "Set Flat Panel mode(Default=OPENLDI)");
+
+module_param(viafb_video_dev, charp, 0);
+MODULE_PARM_DESC(viafb_video_dev, "Specify video devices.");
+
+module_param(viafb_lcd_port, charp, 0);
+MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port.");
+
+module_param(viafb_dvi_port, charp, 0);
+MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port.");
+
+MODULE_LICENSE("GPL");
+#endif
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
new file mode 100644 (file)
index 0000000..a4158e8
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __VIAFBDEV_H__
+#define __VIAFBDEV_H__
+
+#include <linux/proc_fs.h>
+#include <linux/fb.h>
+
+#include "ioctl.h"
+#include "share.h"
+#include "chip.h"
+#include "hw.h"
+#include "via_i2c.h"
+
+#define VERSION_MAJOR       2
+#define VERSION_KERNEL      6  /* For kernel 2.6 */
+
+#define VERSION_OS          0  /* 0: for 32 bits OS, 1: for 64 bits OS */
+#define VERSION_MINOR       4
+
+struct viafb_par {
+       int bpp;
+       int hres;
+       int vres;
+       int linelength;
+       u32 xoffset;
+       u32 yoffset;
+
+       void __iomem *fbmem_virt;       /*framebuffer virtual memory address */
+       void __iomem *io_virt;  /*iospace virtual memory address */
+       unsigned int fbmem;     /*framebuffer physical memory address */
+       unsigned int memsize;   /*size of fbmem */
+       unsigned int io;        /*io space address */
+       unsigned long mmio_base;        /*mmio base address */
+       unsigned long mmio_len; /*mmio base length */
+       u32 fbmem_free;         /* Free FB memory */
+       u32 fbmem_used;         /* Use FB memory size */
+       u32 cursor_start;       /* Cursor Start Address */
+       u32 VQ_start;           /* Virtual Queue Start Address */
+       u32 VQ_end;             /* Virtual Queue End Address */
+       u32 iga_path;
+       struct proc_dir_entry *proc_entry;      /*viafb proc entry */
+       u8 duoview;             /*Is working in duoview mode? */
+
+       /* I2C stuff */
+       struct via_i2c_stuff i2c_stuff;
+
+       /* All the information will be needed to set engine */
+       struct tmds_setting_information *tmds_setting_info;
+       struct crt_setting_information *crt_setting_info;
+       struct lvds_setting_information *lvds_setting_info;
+       struct lvds_setting_information *lvds_setting_info2;
+       struct chip_information *chip_info;
+
+       /* some information related to video playing */
+       int video_on_crt;
+       int video_on_dvi;
+       int video_on_lcd;
+
+};
+struct viafb_modeinfo {
+       u32 xres;
+       u32 yres;
+       int mode_index;
+       char *mode_res;
+};
+extern unsigned int viafb_second_virtual_yres;
+extern unsigned int viafb_second_virtual_xres;
+extern unsigned int viafb_second_offset;
+extern int viafb_second_size;
+extern int viafb_SAMM_ON;
+extern int viafb_dual_fb;
+extern int viafb_LCD2_ON;
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+extern int viafb_accel;
+extern int viafb_hotplug;
+extern int viafb_memsize;
+
+extern int strict_strtoul(const char *cp, unsigned int base,
+       unsigned long *res);
+
+void viafb_memory_pitch_patch(struct fb_info *info);
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
+                         int mode_index);
+int viafb_get_mode_index(int hres, int vres, int flag);
+u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information
+       *plvds_chip_info, u8 index);
+void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
+                             *plvds_setting_info, struct lvds_chip_information
+                             *plvds_chip_info, struct IODATA io_data);
+#endif /* __VIAFBDEV_H__ */
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
new file mode 100644 (file)
index 0000000..6dcf583
--- /dev/null
@@ -0,0 +1,1086 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+struct res_map_refresh res_map_refresh_tbl[] = {
+/*hres, vres, vclock, vmode_refresh*/
+       {480, 640, RES_480X640_60HZ_PIXCLOCK, 60},
+       {640, 480, RES_640X480_60HZ_PIXCLOCK, 60},
+       {640, 480, RES_640X480_75HZ_PIXCLOCK, 75},
+       {640, 480, RES_640X480_85HZ_PIXCLOCK, 85},
+       {640, 480, RES_640X480_100HZ_PIXCLOCK, 100},
+       {640, 480, RES_640X480_120HZ_PIXCLOCK, 120},
+       {720, 480, RES_720X480_60HZ_PIXCLOCK, 60},
+       {720, 576, RES_720X576_60HZ_PIXCLOCK, 60},
+       {800, 480, RES_800X480_60HZ_PIXCLOCK, 60},
+       {800, 600, RES_800X600_60HZ_PIXCLOCK, 60},
+       {800, 600, RES_800X600_75HZ_PIXCLOCK, 75},
+       {800, 600, RES_800X600_85HZ_PIXCLOCK, 85},
+       {800, 600, RES_800X600_100HZ_PIXCLOCK, 100},
+       {800, 600, RES_800X600_120HZ_PIXCLOCK, 120},
+       {848, 480, RES_848X480_60HZ_PIXCLOCK, 60},
+       {856, 480, RES_856X480_60HZ_PIXCLOCK, 60},
+       {1024, 512, RES_1024X512_60HZ_PIXCLOCK, 60},
+       {1024, 600, RES_1024X600_60HZ_PIXCLOCK, 60},
+       {1024, 768, RES_1024X768_60HZ_PIXCLOCK, 60},
+       {1024, 768, RES_1024X768_75HZ_PIXCLOCK, 75},
+       {1024, 768, RES_1024X768_85HZ_PIXCLOCK, 85},
+       {1024, 768, RES_1024X768_100HZ_PIXCLOCK, 100},
+/*  {1152,864, RES_1152X864_70HZ_PIXCLOCK,  70},*/
+       {1152, 864, RES_1152X864_75HZ_PIXCLOCK, 75},
+       {1280, 768, RES_1280X768_60HZ_PIXCLOCK, 60},
+       {1280, 800, RES_1280X800_60HZ_PIXCLOCK, 60},
+       {1280, 960, RES_1280X960_60HZ_PIXCLOCK, 60},
+       {1280, 1024, RES_1280X1024_60HZ_PIXCLOCK, 60},
+       {1280, 1024, RES_1280X1024_75HZ_PIXCLOCK, 75},
+       {1280, 1024, RES_1280X768_85HZ_PIXCLOCK, 85},
+       {1440, 1050, RES_1440X1050_60HZ_PIXCLOCK, 60},
+       {1600, 1200, RES_1600X1200_60HZ_PIXCLOCK, 60},
+       {1600, 1200, RES_1600X1200_75HZ_PIXCLOCK, 75},
+       {1280, 720, RES_1280X720_60HZ_PIXCLOCK, 60},
+       {1920, 1080, RES_1920X1080_60HZ_PIXCLOCK, 60},
+       {1400, 1050, RES_1400X1050_60HZ_PIXCLOCK, 60},
+       {1400, 1050, RES_1400X1050_75HZ_PIXCLOCK, 75},
+       {1368, 768, RES_1368X768_60HZ_PIXCLOCK, 60},
+       {960, 600, RES_960X600_60HZ_PIXCLOCK, 60},
+       {1000, 600, RES_1000X600_60HZ_PIXCLOCK, 60},
+       {1024, 576, RES_1024X576_60HZ_PIXCLOCK, 60},
+       {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60},
+       {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60},
+       {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60},
+       {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60},
+       {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50},
+       {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50},
+       {1360, 768, RES_1360X768_60HZ_PIXCLOCK, 60},
+       {1366, 768, RES_1366X768_50HZ_PIXCLOCK, 50},
+       {1366, 768, RES_1366X768_60HZ_PIXCLOCK, 60},
+       {1440, 900, RES_1440X900_60HZ_PIXCLOCK, 60},
+       {1440, 900, RES_1440X900_75HZ_PIXCLOCK, 75},
+       {1600, 900, RES_1600X900_60HZ_PIXCLOCK, 60},
+       {1600, 1024, RES_1600X1024_60HZ_PIXCLOCK, 60},
+       {1680, 1050, RES_1680X1050_60HZ_PIXCLOCK, 60},
+       {1680, 1050, RES_1680X1050_75HZ_PIXCLOCK, 75},
+       {1792, 1344, RES_1792X1344_60HZ_PIXCLOCK, 60},
+       {1856, 1392, RES_1856X1392_60HZ_PIXCLOCK, 60},
+       {1920, 1200, RES_1920X1200_60HZ_PIXCLOCK, 60},
+       {1920, 1440, RES_1920X1440_60HZ_PIXCLOCK, 60},
+       {1920, 1440, RES_1920X1440_75HZ_PIXCLOCK, 75},
+       {2048, 1536, RES_2048X1536_60HZ_PIXCLOCK, 60}
+};
+
+struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+{VIASR, SR1E, 0x0F, 0x01},
+{VIASR, SR2A, 0xFF, 0x00},
+{VIACR, CR0A, 0xFF, 0x1E},     /* Cursor Start                        */
+{VIACR, CR0B, 0xFF, 0x00},     /* Cursor End                          */
+{VIACR, CR0E, 0xFF, 0x00},     /* Cursor Location High                */
+{VIACR, CR0F, 0xFF, 0x00},     /* Cursor Localtion Low                */
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR62, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR63, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR64, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFF, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR7A, 0xFF, 0x01},     /* LCD Scaling Parameter 1             */
+{VIACR, CR7B, 0xFF, 0x02},     /* LCD Scaling Parameter 2             */
+{VIACR, CR7C, 0xFF, 0x03},     /* LCD Scaling Parameter 3             */
+{VIACR, CR7D, 0xFF, 0x04},     /* LCD Scaling Parameter 4             */
+{VIACR, CR7E, 0xFF, 0x07},     /* LCD Scaling Parameter 5             */
+{VIACR, CR7F, 0xFF, 0x0A},     /* LCD Scaling Parameter 6             */
+{VIACR, CR80, 0xFF, 0x0D},     /* LCD Scaling Parameter 7             */
+{VIACR, CR81, 0xFF, 0x13},     /* LCD Scaling Parameter 8             */
+{VIACR, CR82, 0xFF, 0x16},     /* LCD Scaling Parameter 9             */
+{VIACR, CR83, 0xFF, 0x19},     /* LCD Scaling Parameter 10            */
+{VIACR, CR84, 0xFF, 0x1C},     /* LCD Scaling Parameter 11            */
+{VIACR, CR85, 0xFF, 0x1D},     /* LCD Scaling Parameter 12            */
+{VIACR, CR86, 0xFF, 0x1E},     /* LCD Scaling Parameter 13            */
+{VIACR, CR87, 0xFF, 0x1F},     /* LCD Scaling Parameter 14            */
+{VIACR, CR88, 0xFF, 0x40},     /* LCD Panel Type                      */
+{VIACR, CR89, 0xFF, 0x00},     /* LCD Timing Control 0                */
+{VIACR, CR8A, 0xFF, 0x88},     /* LCD Timing Control 1                */
+{VIACR, CR8B, 0xFF, 0x69},     /* LCD Power Sequence Control 0        */
+{VIACR, CR8C, 0xFF, 0x57},     /* LCD Power Sequence Control 1        */
+{VIACR, CR8D, 0xFF, 0x00},     /* LCD Power Sequence Control 2        */
+{VIACR, CR8E, 0xFF, 0x7B},     /* LCD Power Sequence Control 3        */
+{VIACR, CR8F, 0xFF, 0x03},     /* LCD Power Sequence Control 4        */
+{VIACR, CR90, 0xFF, 0x30},     /* LCD Power Sequence Control 5        */
+{VIACR, CR91, 0xFF, 0xA0},     /* 24/12 bit LVDS Data off             */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00}
+};
+
+/* Video Mode Table for VT3314 chipset*/
+/* Common Setting for Video Mode */
+struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x82},
+{VIASR, SR1B, 0xFF, 0xF0},
+{VIASR, SR1F, 0xFF, 0x00},
+{VIASR, SR1E, 0xFF, 0x01},
+{VIASR, SR22, 0xFF, 0x1F},
+{VIASR, SR2A, 0x0F, 0x00},
+{VIASR, SR2E, 0xFF, 0xFF},
+{VIASR, SR3F, 0xFF, 0xFF},
+{VIASR, SR40, 0xF7, 0x00},
+{VIASR, CR30, 0xFF, 0x04},
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0x7F, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0xFF, 0x31},
+{VIACR, CR41, 0xFF, 0x80},
+{VIACR, CR42, 0xFF, 0x00},
+{VIACR, CR55, 0x80, 0x00},
+{VIACR, CR5D, 0x80, 0x00},     /*Horizontal Retrace Start bit[11] should be 0*/
+{VIACR, CR62, 0xFF, 0x00},     /* Secondary Display Starting Address */
+{VIACR, CR63, 0xFF, 0x00},     /* Secondary Display Starting Address */
+{VIACR, CR64, 0xFF, 0x00},     /* Secondary Display Starting Address */
+{VIACR, CR68, 0xFF, 0x67},     /* Default FIFO For IGA2 */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFD, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR77, 0xFF, 0x00},     /* LCD scaling Factor */
+{VIACR, CR78, 0xFF, 0x00},     /* LCD scaling Factor */
+{VIACR, CR79, 0xFF, 0x00},     /* LCD scaling Factor */
+{VIACR, CR9F, 0x03, 0x00},     /* LCD scaling Factor */
+{VIACR, CR7A, 0xFF, 0x01},     /* LCD Scaling Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02},     /* LCD Scaling Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03},     /* LCD Scaling Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04},     /* LCD Scaling Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07},     /* LCD Scaling Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A},     /* LCD Scaling Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D},     /* LCD Scaling Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13},     /* LCD Scaling Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16},     /* LCD Scaling Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19},     /* LCD Scaling Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C},     /* LCD Scaling Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D},     /* LCD Scaling Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E},     /* LCD Scaling Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F},     /* LCD Scaling Parameter 14 */
+{VIACR, CR88, 0xFF, 0x40},     /* LCD Panel Type */
+{VIACR, CR89, 0xFF, 0x00},     /* LCD Timing Control 0 */
+{VIACR, CR8A, 0xFF, 0x88},     /* LCD Timing Control 1 */
+{VIACR, CR8B, 0xFF, 0x5D},     /* LCD Power Sequence Control 0 */
+{VIACR, CR8C, 0xFF, 0x2B},     /* LCD Power Sequence Control 1 */
+{VIACR, CR8D, 0xFF, 0x6F},     /* LCD Power Sequence Control 2 */
+{VIACR, CR8E, 0xFF, 0x2B},     /* LCD Power Sequence Control 3 */
+{VIACR, CR8F, 0xFF, 0x01},     /* LCD Power Sequence Control 4 */
+{VIACR, CR90, 0xFF, 0x01},     /* LCD Power Sequence Control 5 */
+{VIACR, CR91, 0xFF, 0xA0},     /* 24/12 bit LVDS Data off */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00},
+{VIACR, CR9D, 0xFF, 0x80},
+{VIACR, CR9E, 0xFF, 0x80}
+};
+
+struct io_reg KM400_ModeXregs[] = {
+       {VIASR, SR10, 0xFF, 0x01},      /* Unlock Register                 */
+       {VIASR, SR16, 0xFF, 0x08},      /* Display FIFO threshold Control  */
+       {VIASR, SR17, 0xFF, 0x1F},      /* Display FIFO Control            */
+       {VIASR, SR18, 0xFF, 0x4E},      /* GFX PREQ threshold              */
+       {VIASR, SR1A, 0xFF, 0x0a},      /* GFX PREQ threshold              */
+       {VIASR, SR1F, 0xFF, 0x00},      /* Memory Control 0                */
+       {VIASR, SR1B, 0xFF, 0xF0},      /* Power Management Control 0      */
+       {VIASR, SR1E, 0xFF, 0x01},      /* Power Management Control        */
+       {VIASR, SR20, 0xFF, 0x00},      /* Sequencer Arbiter Control 0     */
+       {VIASR, SR21, 0xFF, 0x00},      /* Sequencer Arbiter Control 1     */
+       {VIASR, SR22, 0xFF, 0x1F},      /* Display Arbiter Control 1       */
+       {VIASR, SR2A, 0xFF, 0x00},      /* Power Management Control 5      */
+       {VIASR, SR2D, 0xFF, 0xFF},      /* Power Management Control 1      */
+       {VIASR, SR2E, 0xFF, 0xFF},      /* Power Management Control 2      */
+       {VIACR, CR0A, 0xFF, 0x1E},      /* Cursor Start                    */
+       {VIACR, CR0B, 0xFF, 0x00},      /* Cursor End                      */
+       {VIACR, CR0E, 0xFF, 0x00},      /* Cursor Location High            */
+       {VIACR, CR0F, 0xFF, 0x00},      /* Cursor Localtion Low            */
+       {VIACR, CR33, 0xFF, 0x00},
+       {VIACR, CR55, 0x80, 0x00},
+       {VIACR, CR5D, 0x80, 0x00},
+       {VIACR, CR36, 0xFF, 0x01},      /* Power Mangement 3                  */
+       {VIACR, CR62, 0xFF, 0x00},      /* Secondary Display Starting Address */
+       {VIACR, CR63, 0xFF, 0x00},      /* Secondary Display Starting Address */
+       {VIACR, CR64, 0xFF, 0x00},      /* Secondary Display Starting Address */
+       {VIACR, CR68, 0xFF, 0x67},      /* Default FIFO For IGA2              */
+       {VIACR, CR6A, 0x20, 0x20},      /* Extended FIFO On                   */
+       {VIACR, CR7A, 0xFF, 0x01},      /* LCD Scaling Parameter 1            */
+       {VIACR, CR7B, 0xFF, 0x02},      /* LCD Scaling Parameter 2            */
+       {VIACR, CR7C, 0xFF, 0x03},      /* LCD Scaling Parameter 3            */
+       {VIACR, CR7D, 0xFF, 0x04},      /* LCD Scaling Parameter 4            */
+       {VIACR, CR7E, 0xFF, 0x07},      /* LCD Scaling Parameter 5            */
+       {VIACR, CR7F, 0xFF, 0x0A},      /* LCD Scaling Parameter 6            */
+       {VIACR, CR80, 0xFF, 0x0D},      /* LCD Scaling Parameter 7            */
+       {VIACR, CR81, 0xFF, 0x13},      /* LCD Scaling Parameter 8            */
+       {VIACR, CR82, 0xFF, 0x16},      /* LCD Scaling Parameter 9            */
+       {VIACR, CR83, 0xFF, 0x19},      /* LCD Scaling Parameter 10           */
+       {VIACR, CR84, 0xFF, 0x1C},      /* LCD Scaling Parameter 11           */
+       {VIACR, CR85, 0xFF, 0x1D},      /* LCD Scaling Parameter 12           */
+       {VIACR, CR86, 0xFF, 0x1E},      /* LCD Scaling Parameter 13           */
+       {VIACR, CR87, 0xFF, 0x1F},      /* LCD Scaling Parameter 14           */
+       {VIACR, CR88, 0xFF, 0x40},      /* LCD Panel Type                     */
+       {VIACR, CR89, 0xFF, 0x00},      /* LCD Timing Control 0               */
+       {VIACR, CR8A, 0xFF, 0x88},      /* LCD Timing Control 1               */
+       {VIACR, CR8B, 0xFF, 0x2D},      /* LCD Power Sequence Control 0       */
+       {VIACR, CR8C, 0xFF, 0x2D},      /* LCD Power Sequence Control 1       */
+       {VIACR, CR8D, 0xFF, 0xC8},      /* LCD Power Sequence Control 2       */
+       {VIACR, CR8E, 0xFF, 0x36},      /* LCD Power Sequence Control 3       */
+       {VIACR, CR8F, 0xFF, 0x00},      /* LCD Power Sequence Control 4       */
+       {VIACR, CR90, 0xFF, 0x10},      /* LCD Power Sequence Control 5       */
+       {VIACR, CR91, 0xFF, 0xA0},      /* 24/12 bit LVDS Data off            */
+       {VIACR, CR96, 0xFF, 0x03},      /* DVP0        ; DVP0 Clock Skew */
+       {VIACR, CR97, 0xFF, 0x03},      /* DFP high    ; DFPH Clock Skew */
+       {VIACR, CR99, 0xFF, 0x03},      /* DFP low           ; DFPL Clock Skew*/
+       {VIACR, CR9B, 0xFF, 0x07}       /* DVI on DVP1       ; DVP1 Clock Skew*/
+};
+
+/* For VT3324: Common Setting for Video Mode */
+struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+{VIASR, SR1B, 0xFF, 0xF0},
+{VIASR, SR1E, 0xFF, 0x01},
+{VIASR, SR2A, 0xFF, 0x00},
+{VIASR, SR2D, 0xFF, 0xFF},     /* VCK and LCK PLL power on.           */
+{VIACR, CR0A, 0xFF, 0x1E},     /* Cursor Start                        */
+{VIACR, CR0B, 0xFF, 0x00},     /* Cursor End                          */
+{VIACR, CR0E, 0xFF, 0x00},     /* Cursor Location High                */
+{VIACR, CR0F, 0xFF, 0x00},     /* Cursor Localtion Low                */
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR47, 0xC8, 0x00},     /* Clear VCK Plus. */
+{VIACR, CR62, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR63, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR64, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CRA3, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFF, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR7A, 0xFF, 0x01},     /* LCD Scaling Parameter 1             */
+{VIACR, CR7B, 0xFF, 0x02},     /* LCD Scaling Parameter 2             */
+{VIACR, CR7C, 0xFF, 0x03},     /* LCD Scaling Parameter 3             */
+{VIACR, CR7D, 0xFF, 0x04},     /* LCD Scaling Parameter 4             */
+{VIACR, CR7E, 0xFF, 0x07},     /* LCD Scaling Parameter 5             */
+{VIACR, CR7F, 0xFF, 0x0A},     /* LCD Scaling Parameter 6             */
+{VIACR, CR80, 0xFF, 0x0D},     /* LCD Scaling Parameter 7             */
+{VIACR, CR81, 0xFF, 0x13},     /* LCD Scaling Parameter 8             */
+{VIACR, CR82, 0xFF, 0x16},     /* LCD Scaling Parameter 9             */
+{VIACR, CR83, 0xFF, 0x19},     /* LCD Scaling Parameter 10            */
+{VIACR, CR84, 0xFF, 0x1C},     /* LCD Scaling Parameter 11            */
+{VIACR, CR85, 0xFF, 0x1D},     /* LCD Scaling Parameter 12            */
+{VIACR, CR86, 0xFF, 0x1E},     /* LCD Scaling Parameter 13            */
+{VIACR, CR87, 0xFF, 0x1F},     /* LCD Scaling Parameter 14            */
+{VIACR, CR88, 0xFF, 0x40},     /* LCD Panel Type                      */
+{VIACR, CR89, 0xFF, 0x00},     /* LCD Timing Control 0                */
+{VIACR, CR8A, 0xFF, 0x88},     /* LCD Timing Control 1                */
+{VIACR, CRD4, 0xFF, 0x81},     /* Second power sequence control       */
+{VIACR, CR8B, 0xFF, 0x5D},     /* LCD Power Sequence Control 0        */
+{VIACR, CR8C, 0xFF, 0x2B},     /* LCD Power Sequence Control 1        */
+{VIACR, CR8D, 0xFF, 0x6F},     /* LCD Power Sequence Control 2        */
+{VIACR, CR8E, 0xFF, 0x2B},     /* LCD Power Sequence Control 3        */
+{VIACR, CR8F, 0xFF, 0x01},     /* LCD Power Sequence Control 4        */
+{VIACR, CR90, 0xFF, 0x01},     /* LCD Power Sequence Control 5        */
+{VIACR, CR91, 0xFF, 0x80},     /* 24/12 bit LVDS Data off             */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00},
+{VIACR, CRD2, 0xFF, 0xFF}      /* TMDS/LVDS control register.         */
+};
+
+/* For VT3353: Common Setting for Video Mode */
+struct io_reg VX800_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+{VIASR, SR1B, 0xFF, 0xF0},
+{VIASR, SR1E, 0xFF, 0x01},
+{VIASR, SR2A, 0xFF, 0x00},
+{VIASR, SR2D, 0xFF, 0xFF},     /* VCK and LCK PLL power on.           */
+{VIACR, CR0A, 0xFF, 0x1E},     /* Cursor Start                        */
+{VIACR, CR0B, 0xFF, 0x00},     /* Cursor End                          */
+{VIACR, CR0E, 0xFF, 0x00},     /* Cursor Location High                */
+{VIACR, CR0F, 0xFF, 0x00},     /* Cursor Localtion Low                */
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR47, 0xC8, 0x00},     /* Clear VCK Plus. */
+{VIACR, CR62, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR63, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR64, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CRA3, 0xFF, 0x00},     /* Secondary Display Starting Address  */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFF, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR7A, 0xFF, 0x01},     /* LCD Scaling Parameter 1             */
+{VIACR, CR7B, 0xFF, 0x02},     /* LCD Scaling Parameter 2             */
+{VIACR, CR7C, 0xFF, 0x03},     /* LCD Scaling Parameter 3             */
+{VIACR, CR7D, 0xFF, 0x04},     /* LCD Scaling Parameter 4             */
+{VIACR, CR7E, 0xFF, 0x07},     /* LCD Scaling Parameter 5             */
+{VIACR, CR7F, 0xFF, 0x0A},     /* LCD Scaling Parameter 6             */
+{VIACR, CR80, 0xFF, 0x0D},     /* LCD Scaling Parameter 7             */
+{VIACR, CR81, 0xFF, 0x13},     /* LCD Scaling Parameter 8             */
+{VIACR, CR82, 0xFF, 0x16},     /* LCD Scaling Parameter 9             */
+{VIACR, CR83, 0xFF, 0x19},     /* LCD Scaling Parameter 10            */
+{VIACR, CR84, 0xFF, 0x1C},     /* LCD Scaling Parameter 11            */
+{VIACR, CR85, 0xFF, 0x1D},     /* LCD Scaling Parameter 12            */
+{VIACR, CR86, 0xFF, 0x1E},     /* LCD Scaling Parameter 13            */
+{VIACR, CR87, 0xFF, 0x1F},     /* LCD Scaling Parameter 14            */
+{VIACR, CR88, 0xFF, 0x40},     /* LCD Panel Type                      */
+{VIACR, CR89, 0xFF, 0x00},     /* LCD Timing Control 0                */
+{VIACR, CR8A, 0xFF, 0x88},     /* LCD Timing Control 1                */
+{VIACR, CRD4, 0xFF, 0x81},     /* Second power sequence control       */
+{VIACR, CR8B, 0xFF, 0x5D},     /* LCD Power Sequence Control 0        */
+{VIACR, CR8C, 0xFF, 0x2B},     /* LCD Power Sequence Control 1        */
+{VIACR, CR8D, 0xFF, 0x6F},     /* LCD Power Sequence Control 2        */
+{VIACR, CR8E, 0xFF, 0x2B},     /* LCD Power Sequence Control 3        */
+{VIACR, CR8F, 0xFF, 0x01},     /* LCD Power Sequence Control 4        */
+{VIACR, CR90, 0xFF, 0x01},     /* LCD Power Sequence Control 5        */
+{VIACR, CR91, 0xFF, 0x80},     /* 24/12 bit LVDS Data off             */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00},
+{VIACR, CRD2, 0xFF, 0xFF}      /* TMDS/LVDS control register.         */
+};
+
+/* Video Mode Table */
+/* Common Setting for Video Mode */
+struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00},
+{VIASR, SR2A, 0x0F, 0x00},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR6A, 0xFF, 0x80},
+{VIACR, CR6A, 0xFF, 0xC0},
+
+{VIACR, CR55, 0x80, 0x00},
+{VIACR, CR5D, 0x80, 0x00},
+
+{VIAGR, GR20, 0xFF, 0x00},
+{VIAGR, GR21, 0xFF, 0x00},
+{VIAGR, GR22, 0xFF, 0x00},
+       /* LCD Parameters */
+{VIACR, CR7A, 0xFF, 0x01},     /* LCD Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02},     /* LCD Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03},     /* LCD Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04},     /* LCD Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07},     /* LCD Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A},     /* LCD Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D},     /* LCD Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13},     /* LCD Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16},     /* LCD Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19},     /* LCD Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C},     /* LCD Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D},     /* LCD Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E},     /* LCD Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F},     /* LCD Parameter 14 */
+
+};
+
+/* Mode:1024X768 */
+struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C},
+{VIASR, 0x18, 0xFF, 0x4C}
+};
+
+struct patch_table res_patch_table[] = {
+       {VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768}
+};
+
+/* struct VPITTable {
+       unsigned char  Misc;
+       unsigned char  SR[StdSR];
+       unsigned char  CR[StdCR];
+       unsigned char  GR[StdGR];
+       unsigned char  AR[StdAR];
+ };*/
+
+struct VPITTable VPIT = {
+       /* Msic */
+       0xC7,
+       /* Sequencer */
+       {0x01, 0x0F, 0x00, 0x0E},
+       /* Graphic Controller */
+       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
+       /* Attribute Controller */
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+        0x01, 0x00, 0x0F, 0x00}
+};
+
+/********************/
+/* Mode Table       */
+/********************/
+
+/* 480x640 */
+struct crt_mode_table CRTM480x640[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_25_175M, M480X640_R60_HSP, M480X640_R60_VSP,
+        {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} }     /* GTF*/
+};
+
+/* 640x480*/
+struct crt_mode_table CRTM640x480[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_25_175M, M640X480_R60_HSP, M640X480_R60_VSP,
+        {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} },
+       {REFRESH_75, CLK_31_500M, M640X480_R75_HSP, M640X480_R75_VSP,
+        {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} },
+       {REFRESH_85, CLK_36_000M, M640X480_R85_HSP, M640X480_R85_VSP,
+        {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} },
+       {REFRESH_100, CLK_43_163M, M640X480_R100_HSP, M640X480_R100_VSP,
+        {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/
+           {REFRESH_120, CLK_52_406M, M640X480_R120_HSP,
+            M640X480_R120_VSP,
+            {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481,
+             3} } /*GTF*/
+};
+
+/*720x480 (GTF)*/
+struct crt_mode_table CRTM720x480[] = {
+       /*r_rate,vclk,hsp,vsp      */
+       /*HT, HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_26_880M, M720X480_R60_HSP, M720X480_R60_VSP,
+        {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} }
+
+};
+
+/*720x576 (GTF)*/
+struct crt_mode_table CRTM720x576[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_32_668M, M720X576_R60_HSP, M720X576_R60_VSP,
+        {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} }
+};
+
+/* 800x480 (CVT) */
+struct crt_mode_table CRTM800x480[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_29_581M, M800X480_R60_HSP, M800X480_R60_VSP,
+        {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} }
+};
+
+/* 800x600*/
+struct crt_mode_table CRTM800x600[] = {
+       /*r_rate,vclk,hsp,vsp     */
+       /*HT,   HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_40_000M, M800X600_R60_HSP, M800X600_R60_VSP,
+        {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} },
+       {REFRESH_75, CLK_49_500M, M800X600_R75_HSP, M800X600_R75_VSP,
+        {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} },
+       {REFRESH_85, CLK_56_250M, M800X600_R85_HSP, M800X600_R85_VSP,
+        {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} },
+       {REFRESH_100, CLK_68_179M, M800X600_R100_HSP, M800X600_R100_VSP,
+        {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} },
+       {REFRESH_120, CLK_83_950M, M800X600_R120_HSP,
+                 M800X600_R120_VSP,
+                 {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601,
+                  3} }
+};
+
+/* 848x480 (CVT) */
+struct crt_mode_table CRTM848x480[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_31_500M, M848X480_R60_HSP, M848X480_R60_VSP,
+        {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} }
+};
+
+/*856x480 (GTF) convert to 852x480*/
+struct crt_mode_table CRTM852x480[] = {
+       /*r_rate,vclk,hsp,vsp     */
+       /*HT,   HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_31_728M, M852X480_R60_HSP, M852X480_R60_VSP,
+       {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} }
+};
+
+/*1024x512 (GTF)*/
+struct crt_mode_table CRTM1024x512[] = {
+       /*r_rate,vclk,hsp,vsp     */
+       /*HT,   HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_41_291M, M1024X512_R60_HSP, M1024X512_R60_VSP,
+        {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} }
+
+};
+
+/* 1024x600*/
+struct crt_mode_table CRTM1024x600[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_48_875M, M1024X600_R60_HSP, M1024X600_R60_VSP,
+        {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} },
+};
+
+/* 1024x768*/
+struct crt_mode_table CRTM1024x768[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_65_000M, M1024X768_R60_HSP, M1024X768_R60_VSP,
+       {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} },
+       {REFRESH_75, CLK_78_750M, M1024X768_R75_HSP, M1024X768_R75_VSP,
+       {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} },
+       {REFRESH_85, CLK_94_500M, M1024X768_R85_HSP, M1024X768_R85_VSP,
+       {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} },
+       {REFRESH_100, CLK_113_309M, M1024X768_R100_HSP, M1024X768_R100_VSP,
+       {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} }
+};
+
+/* 1152x864*/
+struct crt_mode_table CRTM1152x864[] = {
+       /*r_rate,vclk,hsp,vsp      */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_75, CLK_108_000M, M1152X864_R75_HSP, M1152X864_R75_VSP,
+        {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} }
+
+};
+
+/* 1280x720 (HDMI 720P)*/
+struct crt_mode_table CRTM1280x720[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE      */
+       {REFRESH_60, CLK_74_481M, M1280X720_R60_HSP, M1280X720_R60_VSP,
+        {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} },
+       {REFRESH_50, CLK_60_466M, M1280X720_R50_HSP, M1280X720_R50_VSP,
+        {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} }
+};
+
+/*1280x768 (GTF)*/
+struct crt_mode_table CRTM1280x768[] = {
+       /*r_rate,vclk,hsp,vsp     */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_80_136M, M1280X768_R60_HSP, M1280X768_R60_VSP,
+        {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} },
+       {REFRESH_50, CLK_65_178M, M1280X768_R50_HSP, M1280X768_R50_VSP,
+        {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} }
+};
+
+/* 1280x800 (CVT) */
+struct crt_mode_table CRTM1280x800[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_83_375M, M1280X800_R60_HSP, M1280X800_R60_VSP,
+        {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} }
+};
+
+/*1280x960*/
+struct crt_mode_table CRTM1280x960[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_108_000M, M1280X960_R60_HSP, M1280X960_R60_VSP,
+        {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} }
+};
+
+/* 1280x1024*/
+struct crt_mode_table CRTM1280x1024[] = {
+       /*r_rate,vclk,,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_108_000M, M1280X1024_R60_HSP, M1280X1024_R60_VSP,
+        {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025,
+         3} },
+       {REFRESH_75, CLK_135_000M, M1280X1024_R75_HSP, M1280X1024_R75_VSP,
+        {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025,
+         3} },
+       {REFRESH_85, CLK_157_500M, M1280X1024_R85_HSP, M1280X1024_R85_VSP,
+        {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} }
+};
+
+/* 1368x768 (GTF) */
+struct crt_mode_table CRTM1368x768[] = {
+       /* r_rate,  vclk, hsp, vsp */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP,
+        {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }
+};
+
+/*1440x1050 (GTF)*/
+struct crt_mode_table CRTM1440x1050[] = {
+       /*r_rate,vclk,hsp,vsp      */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_125_104M, M1440X1050_R60_HSP, M1440X1050_R60_VSP,
+        {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} }
+};
+
+/* 1600x1200*/
+struct crt_mode_table CRTM1600x1200[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_162_000M, M1600X1200_R60_HSP, M1600X1200_R60_VSP,
+        {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201,
+         3} },
+       {REFRESH_75, CLK_202_500M, M1600X1200_R75_HSP, M1600X1200_R75_VSP,
+        {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} }
+
+};
+
+/* 1680x1050 (CVT) */
+struct crt_mode_table CRTM1680x1050[] = {
+       /* r_rate,          vclk,              hsp,             vsp  */
+       /* HT,  HA,  HBS, HBE, HSS, HSE,    VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_146_760M, M1680x1050_R60_HSP, M1680x1050_R60_VSP,
+        {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053,
+         6} },
+       {REFRESH_75, CLK_187_000M, M1680x1050_R75_HSP, M1680x1050_R75_VSP,
+        {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} }
+};
+
+/* 1680x1050 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1680x1050_RB[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE,    VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_119_000M, M1680x1050_RB_R60_HSP,
+        M1680x1050_RB_R60_VSP,
+        {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} }
+};
+
+/* 1920x1080 (CVT)*/
+struct crt_mode_table CRTM1920x1080[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_172_798M, M1920X1080_R60_HSP, M1920X1080_R60_VSP,
+        {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} }
+};
+
+/* 1920x1080 (CVT with Reduce Blanking) */
+struct crt_mode_table CRTM1920x1080_RB[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_138_400M, M1920X1080_RB_R60_HSP,
+        M1920X1080_RB_R60_VSP,
+        {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} }
+};
+
+/* 1920x1440*/
+struct crt_mode_table CRTM1920x1440[] = {
+       /*r_rate,vclk,hsp,vsp */
+       /*HT,  HA,   HBS,  HBE, HSS,  HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_234_000M, M1920X1440_R60_HSP, M1920X1440_R60_VSP,
+        {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441,
+         3} },
+       {REFRESH_75, CLK_297_500M, M1920X1440_R75_HSP, M1920X1440_R75_VSP,
+        {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} }
+};
+
+/* 1400x1050 (CVT) */
+struct crt_mode_table CRTM1400x1050[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE,   VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_121_750M, M1400X1050_R60_HSP, M1400X1050_R60_VSP,
+        {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053,
+         4} },
+       {REFRESH_75, CLK_156_000M, M1400X1050_R75_HSP, M1400X1050_R75_VSP,
+        {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} }
+};
+
+/* 1400x1050 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1400x1050_RB[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE,   VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_101_000M, M1400X1050_RB_R60_HSP,
+        M1400X1050_RB_R60_VSP,
+        {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} }
+};
+
+/* 960x600 (CVT) */
+struct crt_mode_table CRTM960x600[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_45_250M, M960X600_R60_HSP, M960X600_R60_VSP,
+        {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} }
+};
+
+/* 1000x600 (GTF) */
+struct crt_mode_table CRTM1000x600[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_48_000M, M1000X600_R60_HSP, M1000X600_R60_VSP,
+        {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} }
+};
+
+/* 1024x576 (GTF) */
+struct crt_mode_table CRTM1024x576[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_46_996M, M1024X576_R60_HSP, M1024X576_R60_VSP,
+        {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} }
+};
+
+/* 1088x612 (CVT) */
+struct crt_mode_table CRTM1088x612[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_52_977M, M1088X612_R60_HSP, M1088X612_R60_VSP,
+        {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} }
+};
+
+/* 1152x720 (CVT) */
+struct crt_mode_table CRTM1152x720[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_66_750M, M1152X720_R60_HSP, M1152X720_R60_VSP,
+        {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} }
+};
+
+/* 1200x720 (GTF) */
+struct crt_mode_table CRTM1200x720[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_70_159M, M1200X720_R60_HSP, M1200X720_R60_VSP,
+        {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} }
+};
+
+/* 1280x600 (GTF) */
+struct crt_mode_table CRTM1280x600[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE, VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_61_500M, M1280x600_R60_HSP, M1280x600_R60_VSP,
+        {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} }
+};
+
+/* 1360x768 (CVT) */
+struct crt_mode_table CRTM1360x768[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_84_750M, M1360X768_R60_HSP, M1360X768_R60_VSP,
+        {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} }
+};
+
+/* 1360x768 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1360x768_RB[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_72_000M, M1360X768_RB_R60_HSP,
+        M1360X768_RB_R60_VSP,
+        {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} }
+};
+
+/* 1366x768 (GTF) */
+struct crt_mode_table CRTM1366x768[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP,
+        {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} },
+       {REFRESH_50, CLK_69_924M, M1368X768_R50_HSP, M1368X768_R50_VSP,
+        {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} }
+};
+
+/* 1440x900 (CVT) */
+struct crt_mode_table CRTM1440x900[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_106_500M, M1440X900_R60_HSP, M1440X900_R60_VSP,
+        {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} },
+       {REFRESH_75, CLK_136_700M, M1440X900_R75_HSP, M1440X900_R75_VSP,
+        {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} }
+};
+
+/* 1440x900 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1440x900_RB[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_88_750M, M1440X900_RB_R60_HSP,
+        M1440X900_RB_R60_VSP,
+        {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} }
+};
+
+/* 1600x900 (CVT) */
+struct crt_mode_table CRTM1600x900[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_118_840M, M1600X900_R60_HSP, M1600X900_R60_VSP,
+        {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} }
+};
+
+/* 1600x900 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1600x900_RB[] = {
+       /* r_rate,        vclk,           hsp,        vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_97_750M, M1600X900_RB_R60_HSP,
+        M1600X900_RB_R60_VSP,
+        {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} }
+};
+
+/* 1600x1024 (GTF) */
+struct crt_mode_table CRTM1600x1024[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE,   VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_136_700M, M1600X1024_R60_HSP, M1600X1024_R60_VSP,
+        {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} }
+};
+
+/* 1792x1344 (DMT) */
+struct crt_mode_table CRTM1792x1344[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE,   VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_204_000M, M1792x1344_R60_HSP, M1792x1344_R60_VSP,
+        {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} }
+};
+
+/* 1856x1392 (DMT) */
+struct crt_mode_table CRTM1856x1392[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE,   VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_218_500M, M1856x1392_R60_HSP, M1856x1392_R60_VSP,
+        {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} }
+};
+
+/* 1920x1200 (CVT) */
+struct crt_mode_table CRTM1920x1200[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_193_295M, M1920X1200_R60_HSP, M1920X1200_R60_VSP,
+        {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} }
+};
+
+/* 1920x1200 (CVT with Reduce Blanking) */
+struct crt_mode_table CRTM1920x1200_RB[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
+       {REFRESH_60, CLK_153_920M, M1920X1200_RB_R60_HSP,
+        M1920X1200_RB_R60_VSP,
+        {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} }
+};
+
+/* 2048x1536 (CVT) */
+struct crt_mode_table CRTM2048x1536[] = {
+       /* r_rate,          vclk,              hsp,             vsp   */
+       /* HT,  HA,  HBS, HBE,  HSS, HSE,   VT,  VA,  VBS, VBE,  VSS, VSE */
+       {REFRESH_60, CLK_267_250M, M2048x1536_R60_HSP, M2048x1536_R60_VSP,
+        {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} }
+};
+
+/* Video Mode Table */
+/* struct VideoModeTable {*/
+/*  int                               ModeIndex;*/
+/*  struct crt_mode_table             *crtc;*/
+/*  int                               mode_array;*/
+/* };*/
+struct VideoModeTable CLE266Modes[] = {
+       /* Display : 480x640 (GTF) */
+       {VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)},
+
+       /* Display : 640x480 */
+       {VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)},
+
+       /* Display : 720x480 (GTF) */
+       {VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)},
+
+       /* Display : 720x576 (GTF) */
+       {VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)},
+
+       /* Display : 800x600 */
+       {VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)},
+
+       /* Display : 800x480 (CVT) */
+       {VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)},
+
+       /* Display : 848x480 (CVT) */
+       {VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)},
+
+       /* Display : 852x480 (GTF) */
+       {VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)},
+
+       /* Display : 1024x512 (GTF) */
+       {VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
+
+       /* Display : 1024x600 */
+       {VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
+
+       /* Display : 1024x576 (GTF) */
+       /*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */
+
+       /* Display : 1024x768 */
+       {VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
+
+       /* Display : 1152x864 */
+       {VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
+
+       /* Display : 1280x768 (GTF) */
+       {VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
+
+       /* Display : 960x600 (CVT) */
+       {VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)},
+
+       /* Display : 1000x600 (GTF) */
+       {VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
+
+       /* Display : 1024x576 (GTF) */
+       {VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
+
+       /* Display : 1088x612 (GTF) */
+       {VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
+
+       /* Display : 1152x720 (CVT) */
+       {VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
+
+       /* Display : 1200x720 (GTF) */
+       {VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
+
+       /* Display : 1280x600 (GTF) */
+       {VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
+
+       /* Display : 1280x800 (CVT) */
+       {VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
+
+       /* Display : 1280x800 (GTF) */
+       /*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */
+
+       /* Display : 1280x960 */
+       {VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
+
+       /* Display : 1280x1024 */
+       {VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
+
+       /* Display : 1360x768 (CVT) */
+       {VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
+
+       /* Display : 1360x768 (CVT Reduce Blanking) */
+       {VIA_RES_1360X768_RB, CRTM1360x768_RB,
+        ARRAY_SIZE(CRTM1360x768_RB)},
+
+       /* Display : 1366x768 */
+       {VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
+
+       /* Display : 1368x768 (GTF) */
+       /*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */
+       /* Display : 1368x768 (GTF) */
+       {VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
+
+       /* Display : 1440x900 (CVT) */
+       {VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
+
+       /* Display : 1440x900 (CVT Reduce Blanking) */
+       {VIA_RES_1440X900_RB, CRTM1440x900_RB,
+        ARRAY_SIZE(CRTM1440x900_RB)},
+
+       /* Display : 1440x1050 (GTF) */
+       {VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
+
+       /* Display : 1400x1050 (CVT Reduce Blanking) */
+       {VIA_RES_1400X1050_RB, CRTM1400x1050_RB,
+        ARRAY_SIZE(CRTM1400x1050_RB)},
+
+       /* Display : 1600x900 (CVT) */
+       {VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
+
+       /* Display : 1600x900 (CVT Reduce Blanking) */
+       {VIA_RES_1600X900_RB, CRTM1600x900_RB,
+        ARRAY_SIZE(CRTM1600x900_RB)},
+
+       /* Display : 1600x1024 (GTF) */
+       {VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
+
+       /* Display : 1600x1200 */
+       {VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
+
+       /* Display : 1680x1050 (CVT) */
+       {VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
+
+       /* Display : 1680x1050 (CVT Reduce Blanking) */
+       {VIA_RES_1680X1050_RB, CRTM1680x1050_RB,
+        ARRAY_SIZE(CRTM1680x1050_RB)},
+
+       /* Display : 1792x1344 (DMT) */
+       {VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
+
+       /* Display : 1856x1392 (DMT) */
+       {VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
+
+       /* Display : 1920x1440 */
+       {VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
+
+       /* Display : 2048x1536 */
+       {VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
+
+       /* Display : 1280x720 */
+       {VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
+
+       /* Display : 1920x1080 (CVT) */
+       {VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
+
+       /* Display : 1920x1080 (CVT Reduce Blanking) */
+       {VIA_RES_1920X1080_RB, CRTM1920x1080_RB,
+        ARRAY_SIZE(CRTM1920x1080_RB)},
+
+       /* Display : 1920x1200 (CVT) */
+       {VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
+
+       /* Display : 1920x1200 (CVT Reduce Blanking) */
+       {VIA_RES_1920X1200_RB, CRTM1920x1200_RB,
+        ARRAY_SIZE(CRTM1920x1200_RB)},
+
+       /* Display : 1400x1050 (CVT) */
+       {VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
+};
+struct crt_mode_table CEAM1280x720[] = {
+       {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP,
+        M1280X720_CEA_R60_VSP,
+        /* HT,    HA,   HBS,  HBE,  HSS, HSE,  VT,   VA,  VBS, VBE, VSS, VSE */
+        {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} }
+};
+struct crt_mode_table CEAM1920x1080[] = {
+       {REFRESH_60, CLK_148_500M, M1920X1080_CEA_R60_HSP,
+        M1920X1080_CEA_R60_VSP,
+        /* HT,    HA,   HBS,  HBE,  HSS, HSE,  VT,  VA, VBS, VBE,  VSS, VSE */
+        {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} }
+};
+struct VideoModeTable CEA_HDMI_Modes[] = {
+       /* Display : 1280x720 */
+       {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
+       {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
+};
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
new file mode 100644 (file)
index 0000000..1a5de50
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __VIAMODE_H__
+#define __VIAMODE_H__
+
+#include "global.h"
+
+struct VPITTable {
+       unsigned char Misc;
+       unsigned char SR[StdSR];
+       unsigned char GR[StdGR];
+       unsigned char AR[StdAR];
+};
+
+struct VideoModeTable {
+       int ModeIndex;
+       struct crt_mode_table *crtc;
+       int mode_array;
+};
+
+struct patch_table {
+       int mode_index;
+       int table_length;
+       struct io_reg *io_reg_table;
+};
+
+struct res_map_refresh {
+       int hres;
+       int vres;
+       int pixclock;
+       int vmode_refresh;
+};
+
+#define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl)
+#define NUM_TOTAL_CEA_MODES  ARRAY_SIZE(CEA_HDMI_Modes)
+#define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs)
+#define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs)
+#define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs)
+#define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs)
+#define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs)
+#define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs)
+#define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table)
+#define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes)
+
+/********************/
+/* Mode Table       */
+/********************/
+
+/* 480x640 */
+extern struct crt_mode_table CRTM480x640[1];
+/* 640x480*/
+extern struct crt_mode_table CRTM640x480[5];
+/*720x480 (GTF)*/
+extern struct crt_mode_table CRTM720x480[1];
+/*720x576 (GTF)*/
+extern struct crt_mode_table CRTM720x576[1];
+/* 800x480 (CVT) */
+extern struct crt_mode_table CRTM800x480[1];
+/* 800x600*/
+extern struct crt_mode_table CRTM800x600[5];
+/* 848x480 (CVT) */
+extern struct crt_mode_table CRTM848x480[1];
+/*856x480 (GTF) convert to 852x480*/
+extern struct crt_mode_table CRTM852x480[1];
+/*1024x512 (GTF)*/
+extern struct crt_mode_table CRTM1024x512[1];
+/* 1024x600*/
+extern struct crt_mode_table CRTM1024x600[1];
+/* 1024x768*/
+extern struct crt_mode_table CRTM1024x768[4];
+/* 1152x864*/
+extern struct crt_mode_table CRTM1152x864[1];
+/* 1280x720 (HDMI 720P)*/
+extern struct crt_mode_table CRTM1280x720[2];
+/*1280x768 (GTF)*/
+extern struct crt_mode_table CRTM1280x768[2];
+/* 1280x800 (CVT) */
+extern struct crt_mode_table CRTM1280x800[1];
+/*1280x960*/
+extern struct crt_mode_table CRTM1280x960[1];
+/* 1280x1024*/
+extern struct crt_mode_table CRTM1280x1024[3];
+/* 1368x768 (GTF) */
+extern struct crt_mode_table CRTM1368x768[1];
+/*1440x1050 (GTF)*/
+extern struct crt_mode_table CRTM1440x1050[1];
+/* 1600x1200*/
+extern struct crt_mode_table CRTM1600x1200[2];
+/* 1680x1050 (CVT) */
+extern struct crt_mode_table CRTM1680x1050[2];
+/* 1680x1050 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1680x1050_RB[1];
+/* 1920x1080 (CVT)*/
+extern struct crt_mode_table CRTM1920x1080[1];
+/* 1920x1080 (CVT with Reduce Blanking) */
+extern struct crt_mode_table CRTM1920x1080_RB[1];
+/* 1920x1440*/
+extern struct crt_mode_table CRTM1920x1440[2];
+/* 1400x1050 (CVT) */
+extern struct crt_mode_table CRTM1400x1050[2];
+/* 1400x1050 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1400x1050_RB[1];
+/* 960x600 (CVT) */
+extern struct crt_mode_table CRTM960x600[1];
+/* 1000x600 (GTF) */
+extern struct crt_mode_table CRTM1000x600[1];
+/* 1024x576 (GTF) */
+extern struct crt_mode_table CRTM1024x576[1];
+/* 1088x612 (CVT) */
+extern struct crt_mode_table CRTM1088x612[1];
+/* 1152x720 (CVT) */
+extern struct crt_mode_table CRTM1152x720[1];
+/* 1200x720 (GTF) */
+extern struct crt_mode_table CRTM1200x720[1];
+/* 1280x600 (GTF) */
+extern struct crt_mode_table CRTM1280x600[1];
+/* 1360x768 (CVT) */
+extern struct crt_mode_table CRTM1360x768[1];
+/* 1360x768 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1360x768_RB[1];
+/* 1366x768 (GTF) */
+extern struct crt_mode_table CRTM1366x768[2];
+/* 1440x900 (CVT) */
+extern struct crt_mode_table CRTM1440x900[2];
+/* 1440x900 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1440x900_RB[1];
+/* 1600x900 (CVT) */
+extern struct crt_mode_table CRTM1600x900[1];
+/* 1600x900 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1600x900_RB[1];
+/* 1600x1024 (GTF) */
+extern struct crt_mode_table CRTM1600x1024[1];
+/* 1792x1344 (DMT) */
+extern struct crt_mode_table CRTM1792x1344[1];
+/* 1856x1392 (DMT) */
+extern struct crt_mode_table CRTM1856x1392[1];
+/* 1920x1200 (CVT) */
+extern struct crt_mode_table CRTM1920x1200[1];
+/* 1920x1200 (CVT with Reduce Blanking) */
+extern struct crt_mode_table CRTM1920x1200_RB[1];
+/* 2048x1536 (CVT) */
+extern struct crt_mode_table CRTM2048x1536[1];
+extern struct VideoModeTable CLE266Modes[47];
+extern struct crt_mode_table CEAM1280x720[1];
+extern struct crt_mode_table CEAM1920x1080[1];
+extern struct VideoModeTable CEA_HDMI_Modes[2];
+
+extern struct res_map_refresh res_map_refresh_tbl[61];
+extern struct io_reg CN400_ModeXregs[52];
+extern struct io_reg CN700_ModeXregs[66];
+extern struct io_reg KM400_ModeXregs[55];
+extern struct io_reg CX700_ModeXregs[58];
+extern struct io_reg VX800_ModeXregs[58];
+extern struct io_reg CLE266_ModeXregs[32];
+extern struct io_reg PM1024x768[2];
+extern struct patch_table res_patch_table[1];
+extern struct VPITTable VPIT;
+#endif /* __VIAMODE_H__ */
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
new file mode 100644 (file)
index 0000000..322a9f9
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
+       u8 index)
+{
+       u8 data;
+
+       viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
+       viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data);
+
+       return data;
+}
+
+void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
+                             *plvds_setting_info, struct lvds_chip_information
+                             *plvds_chip_info, struct IODATA io_data)
+{
+       int index, data;
+
+       viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
+
+       index = io_data.Index;
+       data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
+               index);
+       data = (data & (~io_data.Mask)) | io_data.Data;
+
+       viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data);
+}
+
+void viafb_init_lvds_vt1636(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
+{
+       int reg_num, i;
+
+       /* Common settings: */
+       reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636);
+
+       for (i = 0; i < reg_num; i++) {
+               viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+                                        plvds_chip_info,
+                                        COMMON_INIT_TBL_VT1636[i]);
+       }
+
+       /* Input Data Mode Select */
+       if (plvds_setting_info->device_lcd_dualedge) {
+               viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+                                        plvds_chip_info,
+                                        DUAL_CHANNEL_ENABLE_TBL_VT1636[0]);
+       } else {
+               viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+                                        plvds_chip_info,
+                                        SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
+       }
+
+       if (plvds_setting_info->LCDDithering) {
+               viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+                                        plvds_chip_info,
+                                        DITHERING_ENABLE_TBL_VT1636[0]);
+       } else {
+               viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+                                        plvds_chip_info,
+                                        DITHERING_DISABLE_TBL_VT1636[0]);
+       }
+}
+
+void viafb_enable_lvds_vt1636(struct lvds_setting_information
+                       *plvds_setting_info,
+                       struct lvds_chip_information *plvds_chip_info)
+{
+
+       viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
+                                VDD_ON_TBL_VT1636[0]);
+
+       /* Pad on: */
+       switch (plvds_chip_info->output_interface) {
+       case INTERFACE_DVP0:
+               {
+                       viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0);
+                       break;
+               }
+
+       case INTERFACE_DVP1:
+               {
+                       viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
+                       break;
+               }
+
+       case INTERFACE_DFP_LOW:
+               {
+                       viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03);
+                       break;
+               }
+
+       case INTERFACE_DFP_HIGH:
+               {
+                       viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C);
+                       break;
+               }
+
+       }
+}
+
+void viafb_disable_lvds_vt1636(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info)
+{
+
+       viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
+                                VDD_OFF_TBL_VT1636[0]);
+
+       /* Pad off: */
+       switch (plvds_chip_info->output_interface) {
+       case INTERFACE_DVP0:
+               {
+                       viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0);
+                       break;
+               }
+
+       case INTERFACE_DVP1:
+               {
+                       viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
+                       break;
+               }
+
+       case INTERFACE_DFP_LOW:
+               {
+                       viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03);
+                       break;
+               }
+
+       case INTERFACE_DFP_HIGH:
+               {
+                       viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C);
+                       break;
+               }
+
+       }
+}
+
+bool viafb_lvds_identify_vt1636(void)
+{
+       u8 Buffer[2];
+
+       DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
+
+       /* Sense VT1636 LVDS Transmiter */
+       viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
+       VT1636_LVDS_I2C_ADDR;
+
+       /* Check vendor ID first: */
+       viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+       lvds_chip_slave_addr,
+                   0x00, &Buffer[0]);
+       viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+               lvds_chip_slave_addr,
+                   0x01, &Buffer[1]);
+
+       if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
+               return false;
+
+       /* Check Chip ID: */
+       viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+       lvds_chip_slave_addr,
+                   0x02, &Buffer[0]);
+       viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+               lvds_chip_slave_addr,
+                   0x03, &Buffer[1]);
+       if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
+               viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+                       VT1636_LVDS;
+               return true;
+       }
+
+       return false;
+}
+
+static int get_clk_range_index(u32 Clk)
+{
+       if (Clk < DPA_CLK_30M)
+               return DPA_CLK_RANGE_30M;
+       else if (Clk < DPA_CLK_50M)
+               return DPA_CLK_RANGE_30_50M;
+       else if (Clk < DPA_CLK_70M)
+               return DPA_CLK_RANGE_50_70M;
+       else if (Clk < DPA_CLK_100M)
+               return DPA_CLK_RANGE_70_100M;
+       else if (Clk < DPA_CLK_150M)
+               return DPA_CLK_RANGE_100_150M;
+       else
+               return DPA_CLK_RANGE_150M;
+}
+
+static int get_lvds_dpa_setting_index(int panel_size_id,
+                            struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
+                              int tbl_size)
+{
+       int i;
+
+       for (i = 0; i < tbl_size; i++) {
+               if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
+                       return i;
+
+               p_vt1636_dpasetting_tbl++;
+       }
+
+       return 0;
+}
+
+static void set_dpa_vt1636(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
+                   struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
+{
+       struct IODATA io_data;
+
+       io_data.Index = 0x09;
+       io_data.Mask = 0x1F;
+       io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
+       viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+               plvds_chip_info, io_data);
+
+       io_data.Index = 0x08;
+       io_data.Mask = 0x0F;
+       io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
+       viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
+               io_data);
+}
+
+void viafb_vt1636_patch_skew_on_vt3324(
+       struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info)
+{
+       int index, size;
+
+       DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
+
+       /* Graphics DPA settings: */
+       index = get_clk_range_index(plvds_setting_info->vclk);
+       viafb_set_dpa_gfx(plvds_chip_info->output_interface,
+                   &GFX_DPA_SETTING_TBL_VT3324[index]);
+
+       /* LVDS Transmitter DPA settings: */
+       size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
+       index =
+           get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
+                                      VT1636_DPA_SETTING_TBL_VT3324, size);
+       set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
+                      &VT1636_DPA_SETTING_TBL_VT3324[index]);
+}
+
+void viafb_vt1636_patch_skew_on_vt3327(
+       struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info)
+{
+       int index, size;
+
+       DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
+
+       /* Graphics DPA settings: */
+       index = get_clk_range_index(plvds_setting_info->vclk);
+       viafb_set_dpa_gfx(plvds_chip_info->output_interface,
+                   &GFX_DPA_SETTING_TBL_VT3327[index]);
+
+       /* LVDS Transmitter DPA settings: */
+       size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
+       index =
+           get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
+                                      VT1636_DPA_SETTING_TBL_VT3327, size);
+       set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
+                      &VT1636_DPA_SETTING_TBL_VT3327[index]);
+}
+
+void viafb_vt1636_patch_skew_on_vt3364(
+       struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info)
+{
+       int index;
+
+       DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
+
+       /* Graphics DPA settings: */
+       index = get_clk_range_index(plvds_setting_info->vclk);
+       viafb_set_dpa_gfx(plvds_chip_info->output_interface,
+                   &GFX_DPA_SETTING_TBL_VT3364[index]);
+}
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h
new file mode 100644 (file)
index 0000000..2a150c5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _VT1636_H_
+#define _VT1636_H_
+#include "chip.h"
+bool viafb_lvds_identify_vt1636(void);
+void viafb_init_lvds_vt1636(struct lvds_setting_information
+       *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
+void viafb_enable_lvds_vt1636(struct lvds_setting_information
+                       *plvds_setting_info,
+                       struct lvds_chip_information *plvds_chip_info);
+void viafb_disable_lvds_vt1636(struct lvds_setting_information
+                        *plvds_setting_info,
+                        struct lvds_chip_information *plvds_chip_info);
+void viafb_vt1636_patch_skew_on_vt3324(
+       struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info);
+void viafb_vt1636_patch_skew_on_vt3327(
+       struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info);
+void viafb_vt1636_patch_skew_on_vt3364(
+       struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info);
+
+#endif
index 10211e493001582e0a5b27f549a4c9c00f3a6e5a..29e144f81cbe2e8953f1947c745419d1894a0620 100644 (file)
@@ -160,8 +160,10 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
         *     625 us - 60 us - 240 us - 100 ns = 324.9 us
         *
         * We'll wait a bit longer just to be sure.
+        * Was udelay(500), but if it is going to busywait the cpu that long,
+        * might as well come back later.
         */
-       udelay(500);
+       msleep(1);
 
        ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
                DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD |
@@ -274,8 +276,8 @@ static u8 ds1wm_reset_bus(void *data)
        return 0;
 }
 
-static void ds1wm_search(void *data, u8 search_type,
-                        w1_slave_found_callback slave_found)
+static void ds1wm_search(void *data, struct w1_master *master_dev,
+                       u8 search_type, w1_slave_found_callback slave_found)
 {
        struct ds1wm_data *ds1wm_data = data;
        int i;
@@ -313,7 +315,7 @@ static void ds1wm_search(void *data, u8 search_type,
        ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
        ds1wm_reset(ds1wm_data);
 
-       slave_found(ds1wm_data, rom_id);
+       slave_found(master_dev, rom_id);
 }
 
 /* --------------------------------------------------------------------- */
index b63b5e044a4cc7aa641c26ea1de8906f7a4656c4..59ad6e95af8f0b0dded05413115c45bee2d2276b 100644 (file)
@@ -88,7 +88,7 @@
 #define COMM_DT                                0x2000
 #define COMM_SPU                       0x1000
 #define COMM_F                         0x0800
-#define COMM_NTP                       0x0400
+#define COMM_NTF                       0x0400
 #define COMM_ICP                       0x0200
 #define COMM_RST                       0x0100
 
 #define BRANCH_MAIN                    0xCC
 #define BRANCH_AUX                     0x33
 
-/*
- * Duration of the strong pull-up pulse in milliseconds.
- */
-#define PULLUP_PULSE_DURATION          750
-
 /* Status flags */
 #define ST_SPUA                                0x01  /* Strong Pull-up is active */
 #define ST_PRGA                                0x02  /* 12V programming pulse is being generated */
 #define ST_IDLE                                0x20  /* DS2490 is currently idle */
 #define ST_EPOF                                0x80
 
+/* Result Register flags */
+#define RR_DETECT                      0xA5 /* New device detected */
+#define RR_NRS                         0x01 /* Reset no presence or ... */
+#define RR_SH                          0x02 /* short on reset or set path */
+#define RR_APP                         0x04 /* alarming presence on reset */
+#define RR_VPP                         0x08 /* 12V expected not seen */
+#define RR_CMP                         0x10 /* compare error */
+#define RR_CRC                         0x20 /* CRC error detected */
+#define RR_RDP                         0x40 /* redirected page */
+#define RR_EOS                         0x80 /* end of search error */
+
 #define SPEED_NORMAL                   0x00
 #define SPEED_FLEXIBLE                 0x01
 #define SPEED_OVERDRIVE                        0x02
@@ -131,6 +137,15 @@ struct ds_device
 
        int                     ep[NUM_EP];
 
+       /* Strong PullUp
+        * 0: pullup not active, else duration in milliseconds
+        */
+       int                     spu_sleep;
+       /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup
+        * should be active or not for writes.
+        */
+       u16                     spu_bit;
+
        struct w1_bus_master    master;
 };
 
@@ -164,7 +179,6 @@ MODULE_DEVICE_TABLE(usb, ds_id_table);
 static int ds_probe(struct usb_interface *, const struct usb_device_id *);
 static void ds_disconnect(struct usb_interface *);
 
-static inline void ds_dump_status(unsigned char *, unsigned char *, int);
 static int ds_send_control(struct ds_device *, u16, u16);
 static int ds_send_control_cmd(struct ds_device *, u16, u16);
 
@@ -192,7 +206,7 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
 
        return err;
 }
-#if 0
+
 static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
 {
        int err;
@@ -207,7 +221,7 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
 
        return err;
 }
-#endif
+
 static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
 {
        int err;
@@ -223,11 +237,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
        return err;
 }
 
-static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off)
-{
-       printk("%45s: %8x\n", str, buf[off]);
-}
-
 static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
                                 unsigned char *buf, int size)
 {
@@ -248,62 +257,81 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
        return count;
 }
 
-static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
+static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
 {
-       unsigned char buf[64];
-       int count, err = 0, i;
-
-       memcpy(st, buf, sizeof(*st));
+       printk(KERN_INFO "%45s: %8x\n", str, buf[off]);
+}
 
-       count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
-       if (count < 0)
-               return err;
+static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
+{
+       int i;
 
-       printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
+       printk(KERN_INFO "0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
        for (i=0; i<count; ++i)
                printk("%02x ", buf[i]);
-       printk("\n");
+       printk(KERN_INFO "\n");
 
        if (count >= 16) {
-               ds_dump_status(buf, "enable flag", 0);
-               ds_dump_status(buf, "1-wire speed", 1);
-               ds_dump_status(buf, "strong pullup duration", 2);
-               ds_dump_status(buf, "programming pulse duration", 3);
-               ds_dump_status(buf, "pulldown slew rate control", 4);
-               ds_dump_status(buf, "write-1 low time", 5);
-               ds_dump_status(buf, "data sample offset/write-0 recovery time", 6);
-               ds_dump_status(buf, "reserved (test register)", 7);
-               ds_dump_status(buf, "device status flags", 8);
-               ds_dump_status(buf, "communication command byte 1", 9);
-               ds_dump_status(buf, "communication command byte 2", 10);
-               ds_dump_status(buf, "communication command buffer status", 11);
-               ds_dump_status(buf, "1-wire data output buffer status", 12);
-               ds_dump_status(buf, "1-wire data input buffer status", 13);
-               ds_dump_status(buf, "reserved", 14);
-               ds_dump_status(buf, "reserved", 15);
+               ds_print_msg(buf, "enable flag", 0);
+               ds_print_msg(buf, "1-wire speed", 1);
+               ds_print_msg(buf, "strong pullup duration", 2);
+               ds_print_msg(buf, "programming pulse duration", 3);
+               ds_print_msg(buf, "pulldown slew rate control", 4);
+               ds_print_msg(buf, "write-1 low time", 5);
+               ds_print_msg(buf, "data sample offset/write-0 recovery time",
+                       6);
+               ds_print_msg(buf, "reserved (test register)", 7);
+               ds_print_msg(buf, "device status flags", 8);
+               ds_print_msg(buf, "communication command byte 1", 9);
+               ds_print_msg(buf, "communication command byte 2", 10);
+               ds_print_msg(buf, "communication command buffer status", 11);
+               ds_print_msg(buf, "1-wire data output buffer status", 12);
+               ds_print_msg(buf, "1-wire data input buffer status", 13);
+               ds_print_msg(buf, "reserved", 14);
+               ds_print_msg(buf, "reserved", 15);
        }
-
-       memcpy(st, buf, sizeof(*st));
-
-       if (st->status & ST_EPOF) {
-               printk(KERN_INFO "Resetting device after ST_EPOF.\n");
-               err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
-               if (err)
-                       return err;
-               count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
-               if (count < 0)
-                       return err;
-       }
-#if 0
-       if (st->status & ST_IDLE) {
-               printk(KERN_INFO "Resetting pulse after ST_IDLE.\n");
-               err = ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-               if (err)
-                       return err;
+       for (i = 16; i < count; ++i) {
+               if (buf[i] == RR_DETECT) {
+                       ds_print_msg(buf, "new device detect", i);
+                       continue;
+               }
+               ds_print_msg(buf, "Result Register Value: ", i);
+               if (buf[i] & RR_NRS)
+                       printk(KERN_INFO "NRS: Reset no presence or ...\n");
+               if (buf[i] & RR_SH)
+                       printk(KERN_INFO "SH: short on reset or set path\n");
+               if (buf[i] & RR_APP)
+                       printk(KERN_INFO "APP: alarming presence on reset\n");
+               if (buf[i] & RR_VPP)
+                       printk(KERN_INFO "VPP: 12V expected not seen\n");
+               if (buf[i] & RR_CMP)
+                       printk(KERN_INFO "CMP: compare error\n");
+               if (buf[i] & RR_CRC)
+                       printk(KERN_INFO "CRC: CRC error detected\n");
+               if (buf[i] & RR_RDP)
+                       printk(KERN_INFO "RDP: redirected page\n");
+               if (buf[i] & RR_EOS)
+                       printk(KERN_INFO "EOS: end of search error\n");
        }
-#endif
+}
 
-       return err;
+static void ds_reset_device(struct ds_device *dev)
+{
+       ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+       /* Always allow strong pullup which allow individual writes to use
+        * the strong pullup.
+        */
+       if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE))
+               printk(KERN_ERR "ds_reset_device: "
+                       "Error allowing strong pullup\n");
+       /* Chip strong pullup time was cleared. */
+       if (dev->spu_sleep) {
+               /* lower 4 bits are 0, see ds_set_pullup */
+               u8 del = dev->spu_sleep>>4;
+               if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del))
+                       printk(KERN_ERR "ds_reset_device: "
+                               "Error setting duration\n");
+       }
 }
 
 static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
@@ -311,13 +339,27 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
        int count, err;
        struct ds_status st;
 
+       /* Careful on size.  If size is less than what is available in
+        * the input buffer, the device fails the bulk transfer and
+        * clears the input buffer.  It could read the maximum size of
+        * the data buffer, but then do you return the first, last, or
+        * some set of the middle size bytes?  As long as the rest of
+        * the code is correct there will be size bytes waiting.  A
+        * call to ds_wait_status will wait until the device is idle
+        * and any data to be received would have been available.
+        */
        count = 0;
        err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
                                buf, size, &count, 1000);
        if (err < 0) {
+               u8 buf[0x20];
+               int count;
+
                printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
                usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
-               ds_recv_status(dev, &st);
+
+               count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
+               ds_dump_status(dev, buf, count);
                return err;
        }
 
@@ -341,7 +383,8 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
        count = 0;
        err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
        if (err < 0) {
-               printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err);
+               printk(KERN_ERR "Failed to write 1-wire data to ep0x%x: "
+                       "err=%d.\n", dev->ep[EP_DATA_OUT], err);
                return err;
        }
 
@@ -397,7 +440,7 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
        if (err)
                return err;
 
-       err = ds_recv_status(dev, st);
+       err = ds_dump_status(dev, st);
 
        return err;
 }
@@ -420,33 +463,49 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
                        printk("\n");
                }
 #endif
-       } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100);
+       } while (!(buf[0x08] & ST_IDLE) && !(err < 0) && ++count < 100);
+
+       if (err >= 16 && st->status & ST_EPOF) {
+               printk(KERN_INFO "Resetting device after ST_EPOF.\n");
+               ds_reset_device(dev);
+               /* Always dump the device status. */
+               count = 101;
+       }
 
+       /* Dump the status for errors or if there is extended return data.
+        * The extended status includes new device detection (maybe someone
+        * can do something with it).
+        */
+       if (err > 16 || count >= 100 || err < 0)
+               ds_dump_status(dev, buf, err);
 
-       if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {
-               ds_recv_status(dev, st);
+       /* Extended data isn't an error.  Well, a short is, but the dump
+        * would have already told the user that and we can't do anything
+        * about it in software anyway.
+        */
+       if (count >= 100 || err < 0)
                return -1;
-       else
+       else
                return 0;
 }
 
-static int ds_reset(struct ds_device *dev, struct ds_status *st)
+static int ds_reset(struct ds_device *dev)
 {
        int err;
 
-       //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE);
-       err = ds_send_control(dev, 0x43, SPEED_NORMAL);
+       /* Other potentionally interesting flags for reset.
+        *
+        * COMM_NTF: Return result register feedback.  This could be used to
+        * detect some conditions such as short, alarming presence, or
+        * detect if a new device was detected.
+        *
+        * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE:
+        * Select the data transfer rate.
+        */
+       err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL);
        if (err)
                return err;
 
-       ds_wait_status(dev, st);
-#if 0
-       if (st->command_buffer_status) {
-               printk(KERN_INFO "Short circuit.\n");
-               return -EIO;
-       }
-#endif
-
        return 0;
 }
 
@@ -471,60 +530,43 @@ static int ds_set_speed(struct ds_device *dev, int speed)
 }
 #endif  /*  0  */
 
-static int ds_start_pulse(struct ds_device *dev, int delay)
+static int ds_set_pullup(struct ds_device *dev, int delay)
 {
-       int err;
+       int err = 0;
        u8 del = 1 + (u8)(delay >> 4);
-       struct ds_status st;
-
-#if 0
-       err = ds_stop_pulse(dev, 10);
-       if (err)
+       /* Just storing delay would not get the trunication and roundup. */
+       int ms = del<<4;
+
+       /* Enable spu_bit if a delay is set. */
+       dev->spu_bit = delay ? COMM_SPU : 0;
+       /* If delay is zero, it has already been disabled, if the time is
+        * the same as the hardware was last programmed to, there is also
+        * nothing more to do.  Compare with the recalculated value ms
+        * rather than del or delay which can have a different value.
+        */
+       if (delay == 0 || ms == dev->spu_sleep)
                return err;
 
-       err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
-       if (err)
-               return err;
-#endif
        err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);
        if (err)
                return err;
 
-       err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0);
-       if (err)
-               return err;
-
-       mdelay(delay);
-
-       ds_wait_status(dev, &st);
+       dev->spu_sleep = ms;
 
        return err;
 }
 
 static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
 {
-       int err, count;
+       int err;
        struct ds_status st;
-       u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
-       u16 cmd;
 
-       err = ds_send_control(dev, value, 0);
+       err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit ? COMM_D : 0),
+               0);
        if (err)
                return err;
 
-       count = 0;
-       do {
-               err = ds_wait_status(dev, &st);
-               if (err)
-                       return err;
-
-               cmd = st.command0 | (st.command1 << 8);
-       } while (cmd != value && ++count < 10);
-
-       if (err < 0 || count >= 10) {
-               printk(KERN_ERR "Failed to obtain status.\n");
-               return -EINVAL;
-       }
+       ds_wait_status(dev, &st);
 
        err = ds_recv_data(dev, tbit, sizeof(*tbit));
        if (err < 0)
@@ -533,12 +575,18 @@ static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
        return 0;
 }
 
+#if 0
 static int ds_write_bit(struct ds_device *dev, u8 bit)
 {
        int err;
        struct ds_status st;
 
-       err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0);
+       /* Set COMM_ICP to write without a readback.  Note, this will
+        * produce one time slot, a down followed by an up with COMM_D
+        * only determing the timing.
+        */
+       err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP |
+               (bit ? COMM_D : 0), 0);
        if (err)
                return err;
 
@@ -546,6 +594,7 @@ static int ds_write_bit(struct ds_device *dev, u8 bit)
 
        return 0;
 }
+#endif
 
 static int ds_write_byte(struct ds_device *dev, u8 byte)
 {
@@ -553,10 +602,13 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
        struct ds_status st;
        u8 rbyte;
 
-       err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte);
+       err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
        if (err)
                return err;
 
+       if (dev->spu_bit)
+               msleep(dev->spu_sleep);
+
        err = ds_wait_status(dev, &st);
        if (err)
                return err;
@@ -565,8 +617,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
        if (err < 0)
                return err;
 
-       ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-
        return !(byte == rbyte);
 }
 
@@ -602,7 +652,7 @@ static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
        if (err < 0)
                return err;
 
-       err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
+       err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM, len);
        if (err)
                return err;
 
@@ -623,20 +673,19 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
        if (err < 0)
                return err;
 
-       ds_wait_status(dev, &st);
-
-       err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
+       err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len);
        if (err)
                return err;
 
+       if (dev->spu_bit)
+               msleep(dev->spu_sleep);
+
        ds_wait_status(dev, &st);
 
        err = ds_recv_data(dev, buf, len);
        if (err < 0)
                return err;
 
-       ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-
        return !(err == len);
 }
 
@@ -728,6 +777,7 @@ static u8 ds9490r_touch_bit(void *data, u8 bit)
        return ret;
 }
 
+#if 0
 static void ds9490r_write_bit(void *data, u8 bit)
 {
        struct ds_device *dev = data;
@@ -735,13 +785,6 @@ static void ds9490r_write_bit(void *data, u8 bit)
        ds_write_bit(dev, bit);
 }
 
-static void ds9490r_write_byte(void *data, u8 byte)
-{
-       struct ds_device *dev = data;
-
-       ds_write_byte(dev, byte);
-}
-
 static u8 ds9490r_read_bit(void *data)
 {
        struct ds_device *dev = data;
@@ -754,6 +797,14 @@ static u8 ds9490r_read_bit(void *data)
 
        return bit & 1;
 }
+#endif
+
+static void ds9490r_write_byte(void *data, u8 byte)
+{
+       struct ds_device *dev = data;
+
+       ds_write_byte(dev, byte);
+}
 
 static u8 ds9490r_read_byte(void *data)
 {
@@ -790,31 +841,58 @@ static u8 ds9490r_read_block(void *data, u8 *buf, int len)
 static u8 ds9490r_reset(void *data)
 {
        struct ds_device *dev = data;
-       struct ds_status st;
        int err;
 
-       memset(&st, 0, sizeof(st));
-
-       err = ds_reset(dev, &st);
+       err = ds_reset(dev);
        if (err)
                return 1;
 
        return 0;
 }
 
+static u8 ds9490r_set_pullup(void *data, int delay)
+{
+       struct ds_device *dev = data;
+
+       if (ds_set_pullup(dev, delay))
+               return 1;
+
+       return 0;
+}
+
 static int ds_w1_init(struct ds_device *dev)
 {
        memset(&dev->master, 0, sizeof(struct w1_bus_master));
 
+       /* Reset the device as it can be in a bad state.
+        * This is necessary because a block write will wait for data
+        * to be placed in the output buffer and block any later
+        * commands which will keep accumulating and the device will
+        * not be idle.  Another case is removing the ds2490 module
+        * while a bus search is in progress, somehow a few commands
+        * get through, but the input transfers fail leaving data in
+        * the input buffer.  This will cause the next read to fail
+        * see the note in ds_recv_data.
+        */
+       ds_reset_device(dev);
+
        dev->master.data        = dev;
        dev->master.touch_bit   = &ds9490r_touch_bit;
+       /* read_bit and write_bit in w1_bus_master are expected to set and
+        * sample the line level.  For write_bit that means it is expected to
+        * set it to that value and leave it there.  ds2490 only supports an
+        * individual time slot at the lowest level.  The requirement from
+        * pulling the bus state down to reading the state is 15us, something
+        * that isn't realistic on the USB bus anyway.
        dev->master.read_bit    = &ds9490r_read_bit;
        dev->master.write_bit   = &ds9490r_write_bit;
+       */
        dev->master.read_byte   = &ds9490r_read_byte;
        dev->master.write_byte  = &ds9490r_write_byte;
        dev->master.read_block  = &ds9490r_read_block;
        dev->master.write_block = &ds9490r_write_block;
        dev->master.reset_bus   = &ds9490r_reset;
+       dev->master.set_pullup  = &ds9490r_set_pullup;
 
        return w1_add_master_device(&dev->master);
 }
@@ -838,6 +916,8 @@ static int ds_probe(struct usb_interface *intf,
                printk(KERN_INFO "Failed to allocate new DS9490R structure.\n");
                return -ENOMEM;
        }
+       dev->spu_sleep = 0;
+       dev->spu_bit = 0;
        dev->udev = usb_get_dev(udev);
        if (!dev->udev) {
                err = -ENOMEM;
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c
new file mode 100644 (file)
index 0000000..2c6c0cf
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * w1_ds2431.c - w1 family 2d (DS2431) driver
+ *
+ * Copyright (c) 2008 Bernhard Weirich <bernhard.weirich@riedel.net>
+ *
+ * Heavily inspired by w1_DS2433 driver from Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+#include "../w1_family.h"
+
+#define W1_F2D_EEPROM_SIZE             128
+#define W1_F2D_PAGE_COUNT              4
+#define W1_F2D_PAGE_BITS               5
+#define W1_F2D_PAGE_SIZE               (1<<W1_F2D_PAGE_BITS)
+#define W1_F2D_PAGE_MASK               0x1F
+
+#define W1_F2D_SCRATCH_BITS  3
+#define W1_F2D_SCRATCH_SIZE  (1<<W1_F2D_SCRATCH_BITS)
+#define W1_F2D_SCRATCH_MASK  (W1_F2D_SCRATCH_SIZE-1)
+
+#define W1_F2D_READ_EEPROM     0xF0
+#define W1_F2D_WRITE_SCRATCH   0x0F
+#define W1_F2D_READ_SCRATCH    0xAA
+#define W1_F2D_COPY_SCRATCH    0x55
+
+
+#define W1_F2D_TPROG_MS                11
+
+#define W1_F2D_READ_RETRIES            10
+#define W1_F2D_READ_MAXLEN             8
+
+/*
+ * Check the file size bounds and adjusts count as needed.
+ * This would not be needed if the file size didn't reset to 0 after a write.
+ */
+static inline size_t w1_f2d_fix_count(loff_t off, size_t count, size_t size)
+{
+       if (off > size)
+               return 0;
+
+       if ((off + count) > size)
+               return size - off;
+
+       return count;
+}
+
+/*
+ * Read a block from W1 ROM two times and compares the results.
+ * If they are equal they are returned, otherwise the read
+ * is repeated W1_F2D_READ_RETRIES times.
+ *
+ * count must not exceed W1_F2D_READ_MAXLEN.
+ */
+static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf)
+{
+       u8 wrbuf[3];
+       u8 cmp[W1_F2D_READ_MAXLEN];
+       int tries = W1_F2D_READ_RETRIES;
+
+       do {
+               wrbuf[0] = W1_F2D_READ_EEPROM;
+               wrbuf[1] = off & 0xff;
+               wrbuf[2] = off >> 8;
+
+               if (w1_reset_select_slave(sl))
+                       return -1;
+
+               w1_write_block(sl->master, wrbuf, 3);
+               w1_read_block(sl->master, buf, count);
+
+               if (w1_reset_select_slave(sl))
+                       return -1;
+
+               w1_write_block(sl->master, wrbuf, 3);
+               w1_read_block(sl->master, cmp, count);
+
+               if (!memcmp(cmp, buf, count))
+                       return 0;
+       } while (--tries);
+
+       dev_err(&sl->dev, "proof reading failed %d times\n",
+                       W1_F2D_READ_RETRIES);
+
+       return -1;
+}
+
+static ssize_t w1_f2d_read_bin(struct kobject *kobj,
+                              struct bin_attribute *bin_attr,
+                              char *buf, loff_t off, size_t count)
+{
+       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+       int todo = count;
+
+       count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
+       if (count == 0)
+               return 0;
+
+       mutex_lock(&sl->master->mutex);
+
+       /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */
+       while (todo > 0) {
+               int block_read;
+
+               if (todo >= W1_F2D_READ_MAXLEN)
+                       block_read = W1_F2D_READ_MAXLEN;
+               else
+                       block_read = todo;
+
+               if (w1_f2d_readblock(sl, off, block_read, buf) < 0)
+                       count = -EIO;
+
+               todo -= W1_F2D_READ_MAXLEN;
+               buf += W1_F2D_READ_MAXLEN;
+               off += W1_F2D_READ_MAXLEN;
+       }
+
+       mutex_unlock(&sl->master->mutex);
+
+       return count;
+}
+
+/*
+ * Writes to the scratchpad and reads it back for verification.
+ * Then copies the scratchpad to EEPROM.
+ * The data must be aligned at W1_F2D_SCRATCH_SIZE bytes and
+ * must be W1_F2D_SCRATCH_SIZE bytes long.
+ * The master must be locked.
+ *
+ * @param sl   The slave structure
+ * @param addr Address for the write
+ * @param len   length must be <= (W1_F2D_PAGE_SIZE - (addr & W1_F2D_PAGE_MASK))
+ * @param data The data to write
+ * @return     0=Success -1=failure
+ */
+static int w1_f2d_write(struct w1_slave *sl, int addr, int len, const u8 *data)
+{
+       int tries = W1_F2D_READ_RETRIES;
+       u8 wrbuf[4];
+       u8 rdbuf[W1_F2D_SCRATCH_SIZE + 3];
+       u8 es = (addr + len - 1) % W1_F2D_SCRATCH_SIZE;
+
+retry:
+
+       /* Write the data to the scratchpad */
+       if (w1_reset_select_slave(sl))
+               return -1;
+
+       wrbuf[0] = W1_F2D_WRITE_SCRATCH;
+       wrbuf[1] = addr & 0xff;
+       wrbuf[2] = addr >> 8;
+
+       w1_write_block(sl->master, wrbuf, 3);
+       w1_write_block(sl->master, data, len);
+
+       /* Read the scratchpad and verify */
+       if (w1_reset_select_slave(sl))
+               return -1;
+
+       w1_write_8(sl->master, W1_F2D_READ_SCRATCH);
+       w1_read_block(sl->master, rdbuf, len + 3);
+
+       /* Compare what was read against the data written */
+       if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
+           (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) {
+
+               if (--tries)
+                       goto retry;
+
+               dev_err(&sl->dev,
+                       "could not write to eeprom, scratchpad compare failed %d times\n",
+                       W1_F2D_READ_RETRIES);
+
+               return -1;
+       }
+
+       /* Copy the scratchpad to EEPROM */
+       if (w1_reset_select_slave(sl))
+               return -1;
+
+       wrbuf[0] = W1_F2D_COPY_SCRATCH;
+       wrbuf[3] = es;
+       w1_write_block(sl->master, wrbuf, 4);
+
+       /* Sleep for tprog ms to wait for the write to complete */
+       msleep(W1_F2D_TPROG_MS);
+
+       /* Reset the bus to wake up the EEPROM  */
+       w1_reset_bus(sl->master);
+
+       return 0;
+}
+
+static ssize_t w1_f2d_write_bin(struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t off, size_t count)
+{
+       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+       int addr, len;
+       int copy;
+
+       count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
+       if (count == 0)
+               return 0;
+
+       mutex_lock(&sl->master->mutex);
+
+       /* Can only write data in blocks of the size of the scratchpad */
+       addr = off;
+       len = count;
+       while (len > 0) {
+
+               /* if len too short or addr not aligned */
+               if (len < W1_F2D_SCRATCH_SIZE || addr & W1_F2D_SCRATCH_MASK) {
+                       char tmp[W1_F2D_SCRATCH_SIZE];
+
+                       /* read the block and update the parts to be written */
+                       if (w1_f2d_readblock(sl, addr & ~W1_F2D_SCRATCH_MASK,
+                                       W1_F2D_SCRATCH_SIZE, tmp)) {
+                               count = -EIO;
+                               goto out_up;
+                       }
+
+                       /* copy at most to the boundary of the PAGE or len */
+                       copy = W1_F2D_SCRATCH_SIZE -
+                               (addr & W1_F2D_SCRATCH_MASK);
+
+                       if (copy > len)
+                               copy = len;
+
+                       memcpy(&tmp[addr & W1_F2D_SCRATCH_MASK], buf, copy);
+                       if (w1_f2d_write(sl, addr & ~W1_F2D_SCRATCH_MASK,
+                                       W1_F2D_SCRATCH_SIZE, tmp) < 0) {
+                               count = -EIO;
+                               goto out_up;
+                       }
+               } else {
+
+                       copy = W1_F2D_SCRATCH_SIZE;
+                       if (w1_f2d_write(sl, addr, copy, buf) < 0) {
+                               count = -EIO;
+                               goto out_up;
+                       }
+               }
+               buf += copy;
+               addr += copy;
+               len -= copy;
+       }
+
+out_up:
+       mutex_unlock(&sl->master->mutex);
+
+       return count;
+}
+
+static struct bin_attribute w1_f2d_bin_attr = {
+       .attr = {
+               .name = "eeprom",
+               .mode = S_IRUGO | S_IWUSR,
+       },
+       .size = W1_F2D_EEPROM_SIZE,
+       .read = w1_f2d_read_bin,
+       .write = w1_f2d_write_bin,
+};
+
+static int w1_f2d_add_slave(struct w1_slave *sl)
+{
+       return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
+}
+
+static void w1_f2d_remove_slave(struct w1_slave *sl)
+{
+       sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
+}
+
+static struct w1_family_ops w1_f2d_fops = {
+       .add_slave      = w1_f2d_add_slave,
+       .remove_slave   = w1_f2d_remove_slave,
+};
+
+static struct w1_family w1_family_2d = {
+       .fid = W1_EEPROM_DS2431,
+       .fops = &w1_f2d_fops,
+};
+
+static int __init w1_f2d_init(void)
+{
+       return w1_register_family(&w1_family_2d);
+}
+
+static void __exit w1_f2d_fini(void)
+{
+       w1_unregister_family(&w1_family_2d);
+}
+
+module_init(w1_f2d_init);
+module_exit(w1_f2d_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Bernhard Weirich <bernhard.weirich@riedel.net>");
+MODULE_DESCRIPTION("w1 family 2d driver for DS2431, 1kb EEPROM");
index fb28acaeed6c4ab01235f09b764b8d0b7e1b20b6..2c8dff9f77da13396b0d02207e15d486ddbd5d4e 100644 (file)
@@ -37,31 +37,33 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
 
+/* Allow the strong pullup to be disabled, but default to enabled.
+ * If it was disabled a parasite powered device might not get the require
+ * current to do a temperature conversion.  If it is enabled parasite powered
+ * devices have a better chance of getting the current required.
+ */
+static int w1_strong_pullup = 1;
+module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
 static u8 bad_roms[][9] = {
                                {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
                                {}
                        };
 
-static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *,
-                                char *, loff_t, size_t);
+static ssize_t w1_therm_read(struct device *device,
+       struct device_attribute *attr, char *buf);
 
-static struct bin_attribute w1_therm_bin_attr = {
-       .attr = {
-               .name = "w1_slave",
-               .mode = S_IRUGO,
-       },
-       .size = W1_SLAVE_DATA_SIZE,
-       .read = w1_therm_read_bin,
-};
+static struct device_attribute w1_therm_attr =
+       __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
 
 static int w1_therm_add_slave(struct w1_slave *sl)
 {
-       return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+       return device_create_file(&sl->dev, &w1_therm_attr);
 }
 
 static void w1_therm_remove_slave(struct w1_slave *sl)
 {
-       sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+       device_remove_file(&sl->dev, &w1_therm_attr);
 }
 
 static struct w1_family_ops w1_therm_fops = {
@@ -160,30 +162,19 @@ static int w1_therm_check_rom(u8 rom[9])
        return 0;
 }
 
-static ssize_t w1_therm_read_bin(struct kobject *kobj,
-                                struct bin_attribute *bin_attr,
-                                char *buf, loff_t off, size_t count)
+static ssize_t w1_therm_read(struct device *device,
+       struct device_attribute *attr, char *buf)
 {
-       struct w1_slave *sl = kobj_to_w1_slave(kobj);
+       struct w1_slave *sl = dev_to_w1_slave(device);
        struct w1_master *dev = sl->master;
        u8 rom[9], crc, verdict;
        int i, max_trying = 10;
+       ssize_t c = PAGE_SIZE;
 
-       mutex_lock(&sl->master->mutex);
+       mutex_lock(&dev->mutex);
 
-       if (off > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       if (off + count > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-
-       memset(buf, 0, count);
        memset(rom, 0, sizeof(rom));
 
-       count = 0;
        verdict = 0;
        crc = 0;
 
@@ -192,15 +183,20 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
                        int count = 0;
                        unsigned int tm = 750;
 
+                       /* 750ms strong pullup (or delay) after the convert */
+                       if (w1_strong_pullup)
+                               w1_next_pullup(dev, tm);
                        w1_write_8(dev, W1_CONVERT_TEMP);
-
-                       msleep(tm);
+                       if (!w1_strong_pullup)
+                               msleep(tm);
 
                        if (!w1_reset_select_slave(sl)) {
 
                                w1_write_8(dev, W1_READ_SCRATCHPAD);
                                if ((count = w1_read_block(dev, rom, 9)) != 9) {
-                                       dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
+                                       dev_warn(device, "w1_read_block() "
+                                               "returned %u instead of 9.\n",
+                                               count);
                                }
 
                                crc = w1_calc_crc8(rom, 8);
@@ -215,22 +211,22 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
        }
 
        for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", rom[i]);
-       count += sprintf(buf + count, ": crc=%02x %s\n",
+               c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
+       c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
                           crc, (verdict) ? "YES" : "NO");
        if (verdict)
                memcpy(sl->rom, rom, sizeof(sl->rom));
        else
-               dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n");
+               dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
 
        for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", sl->rom[i]);
+               c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
 
-       count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
-out:
+       c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
+               w1_convert_temp(rom, sl->family->fid));
        mutex_unlock(&dev->mutex);
 
-       return count;
+       return PAGE_SIZE - c;
 }
 
 static int __init w1_therm_init(void)
index 7293c9b11f9160e2b80f89e8e9c63d6bdfd6553f..3b615d4022ee98f8abd155d33301220a51386cae 100644 (file)
@@ -46,19 +46,17 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
 
 static int w1_timeout = 10;
-static int w1_control_timeout = 1;
 int w1_max_slave_count = 10;
 int w1_max_slave_ttl = 10;
 
 module_param_named(timeout, w1_timeout, int, 0);
-module_param_named(control_timeout, w1_control_timeout, int, 0);
 module_param_named(max_slave_count, w1_max_slave_count, int, 0);
 module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
 
 DEFINE_MUTEX(w1_mlock);
 LIST_HEAD(w1_masters);
 
-static struct task_struct *w1_control_thread;
+static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn);
 
 static int w1_master_match(struct device *dev, struct device_driver *drv)
 {
@@ -83,10 +81,10 @@ static void w1_slave_release(struct device *dev)
 {
        struct w1_slave *sl = dev_to_w1_slave(dev);
 
-       printk("%s: Releasing %s.\n", __func__, sl->name);
+       dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
 
        while (atomic_read(&sl->refcnt)) {
-               printk("Waiting for %s to become free: refcnt=%d.\n",
+               dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
                                sl->name, atomic_read(&sl->refcnt));
                if (msleep_interruptible(1000))
                        flush_signals(current);
@@ -105,35 +103,20 @@ static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *a
        return sprintf(buf, "%s\n", sl->name);
 }
 
-static ssize_t w1_slave_read_id(struct kobject *kobj,
-                               struct bin_attribute *bin_attr,
-                               char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read_id(struct device *dev,
+       struct device_attribute *attr, char *buf)
 {
-       struct w1_slave *sl = kobj_to_w1_slave(kobj);
-
-       if (off > 8) {
-               count = 0;
-       } else {
-               if (off + count > 8)
-                       count = 8 - off;
-
-               memcpy(buf, (u8 *)&sl->reg_num, count);
-       }
+       struct w1_slave *sl = dev_to_w1_slave(dev);
+       ssize_t count = sizeof(sl->reg_num);
 
+       memcpy(buf, (u8 *)&sl->reg_num, count);
        return count;
 }
 
 static struct device_attribute w1_slave_attr_name =
        __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
-
-static struct bin_attribute w1_slave_attr_bin_id = {
-      .attr = {
-              .name = "id",
-              .mode = S_IRUGO,
-      },
-      .size = 8,
-      .read = w1_slave_read_id,
-};
+static struct device_attribute w1_slave_attr_id =
+       __ATTR(id, S_IRUGO, w1_slave_read_id, NULL);
 
 /* Default family */
 
@@ -250,11 +233,16 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
                                                struct device_attribute *attr,
                                                const char * buf, size_t count)
 {
+       long tmp;
        struct w1_master *md = dev_to_w1_master(dev);
 
+       if (strict_strtol(buf, 0, &tmp) == -EINVAL)
+               return -EINVAL;
+
        mutex_lock(&md->mutex);
-       md->search_count = simple_strtol(buf, NULL, 0);
+       md->search_count = tmp;
        mutex_unlock(&md->mutex);
+       wake_up_process(md->thread);
 
        return count;
 }
@@ -273,6 +261,38 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
        return count;
 }
 
+static ssize_t w1_master_attribute_store_pullup(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf, size_t count)
+{
+       long tmp;
+       struct w1_master *md = dev_to_w1_master(dev);
+
+       if (strict_strtol(buf, 0, &tmp) == -EINVAL)
+               return -EINVAL;
+
+       mutex_lock(&md->mutex);
+       md->enable_pullup = tmp;
+       mutex_unlock(&md->mutex);
+       wake_up_process(md->thread);
+
+       return count;
+}
+
+static ssize_t w1_master_attribute_show_pullup(struct device *dev,
+                                              struct device_attribute *attr,
+                                              char *buf)
+{
+       struct w1_master *md = dev_to_w1_master(dev);
+       ssize_t count;
+
+       mutex_lock(&md->mutex);
+       count = sprintf(buf, "%d\n", md->enable_pullup);
+       mutex_unlock(&md->mutex);
+
+       return count;
+}
+
 static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct w1_master *md = dev_to_w1_master(dev);
@@ -324,7 +344,8 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
        return count;
 }
 
-static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t w1_master_attribute_show_slaves(struct device *dev,
+       struct device_attribute *attr, char *buf)
 {
        struct w1_master *md = dev_to_w1_master(dev);
        int c = PAGE_SIZE;
@@ -349,6 +370,135 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device
        return PAGE_SIZE - c;
 }
 
+static ssize_t w1_master_attribute_show_add(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       int c = PAGE_SIZE;
+       c -= snprintf(buf+PAGE_SIZE - c, c,
+               "write device id xx-xxxxxxxxxxxx to add slave\n");
+       return PAGE_SIZE - c;
+}
+
+static int w1_atoreg_num(struct device *dev, const char *buf, size_t count,
+       struct w1_reg_num *rn)
+{
+       unsigned int family;
+       unsigned long long id;
+       int i;
+       u64 rn64_le;
+
+       /* The CRC value isn't read from the user because the sysfs directory
+        * doesn't include it and most messages from the bus search don't
+        * print it either.  It would be unreasonable for the user to then
+        * provide it.
+        */
+       const char *error_msg = "bad slave string format, expecting "
+               "ff-dddddddddddd\n";
+
+       if (buf[2] != '-') {
+               dev_err(dev, "%s", error_msg);
+               return -EINVAL;
+       }
+       i = sscanf(buf, "%02x-%012llx", &family, &id);
+       if (i != 2) {
+               dev_err(dev, "%s", error_msg);
+               return -EINVAL;
+       }
+       rn->family = family;
+       rn->id = id;
+
+       rn64_le = cpu_to_le64(*(u64 *)rn);
+       rn->crc = w1_calc_crc8((u8 *)&rn64_le, 7);
+
+#if 0
+       dev_info(dev, "With CRC device is %02x.%012llx.%02x.\n",
+                 rn->family, (unsigned long long)rn->id, rn->crc);
+#endif
+
+       return 0;
+}
+
+/* Searches the slaves in the w1_master and returns a pointer or NULL.
+ * Note: must hold the mutex
+ */
+static struct w1_slave *w1_slave_search_device(struct w1_master *dev,
+       struct w1_reg_num *rn)
+{
+       struct w1_slave *sl;
+       list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
+               if (sl->reg_num.family == rn->family &&
+                               sl->reg_num.id == rn->id &&
+                               sl->reg_num.crc == rn->crc) {
+                       return sl;
+               }
+       }
+       return NULL;
+}
+
+static ssize_t w1_master_attribute_store_add(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf, size_t count)
+{
+       struct w1_master *md = dev_to_w1_master(dev);
+       struct w1_reg_num rn;
+       struct w1_slave *sl;
+       ssize_t result = count;
+
+       if (w1_atoreg_num(dev, buf, count, &rn))
+               return -EINVAL;
+
+       mutex_lock(&md->mutex);
+       sl = w1_slave_search_device(md, &rn);
+       /* It would be nice to do a targeted search one the one-wire bus
+        * for the new device to see if it is out there or not.  But the
+        * current search doesn't support that.
+        */
+       if (sl) {
+               dev_info(dev, "Device %s already exists\n", sl->name);
+               result = -EINVAL;
+       } else {
+               w1_attach_slave_device(md, &rn);
+       }
+       mutex_unlock(&md->mutex);
+
+       return result;
+}
+
+static ssize_t w1_master_attribute_show_remove(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       int c = PAGE_SIZE;
+       c -= snprintf(buf+PAGE_SIZE - c, c,
+               "write device id xx-xxxxxxxxxxxx to remove slave\n");
+       return PAGE_SIZE - c;
+}
+
+static ssize_t w1_master_attribute_store_remove(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf, size_t count)
+{
+       struct w1_master *md = dev_to_w1_master(dev);
+       struct w1_reg_num rn;
+       struct w1_slave *sl;
+       ssize_t result = count;
+
+       if (w1_atoreg_num(dev, buf, count, &rn))
+               return -EINVAL;
+
+       mutex_lock(&md->mutex);
+       sl = w1_slave_search_device(md, &rn);
+       if (sl) {
+               w1_slave_detach(sl);
+       } else {
+               dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family,
+                       (unsigned long long)rn.id);
+               result = -EINVAL;
+       }
+       mutex_unlock(&md->mutex);
+
+       return result;
+}
+
 #define W1_MASTER_ATTR_RO(_name, _mode)                                \
        struct device_attribute w1_master_attribute_##_name =   \
                __ATTR(w1_master_##_name, _mode,                \
@@ -368,6 +518,9 @@ static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
 static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
 static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
 static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUGO);
 
 static struct attribute *w1_master_default_attrs[] = {
        &w1_master_attribute_name.attr,
@@ -378,6 +531,9 @@ static struct attribute *w1_master_default_attrs[] = {
        &w1_master_attribute_timeout.attr,
        &w1_master_attribute_pointer.attr,
        &w1_master_attribute_search.attr,
+       &w1_master_attribute_pullup.attr,
+       &w1_master_attribute_add.attr,
+       &w1_master_attribute_remove.attr,
        NULL
 };
 
@@ -390,7 +546,7 @@ int w1_create_master_attributes(struct w1_master *master)
        return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);
 }
 
-static void w1_destroy_master_attributes(struct w1_master *master)
+void w1_destroy_master_attributes(struct w1_master *master)
 {
        sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
 }
@@ -479,7 +635,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
        }
 
        /* Create "id" entry */
-       err = sysfs_create_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+       err = device_create_file(&sl->dev, &w1_slave_attr_id);
        if (err < 0) {
                dev_err(&sl->dev,
                        "sysfs file creation for [%s] failed. err=%d\n",
@@ -501,7 +657,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
        return 0;
 
 out_rem2:
-       sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+       device_remove_file(&sl->dev, &w1_slave_attr_id);
 out_rem1:
        device_remove_file(&sl->dev, &w1_slave_attr_name);
 out_unreg:
@@ -567,7 +723,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
        return 0;
 }
 
-static void w1_slave_detach(struct w1_slave *sl)
+void w1_slave_detach(struct w1_slave *sl)
 {
        struct w1_netlink_msg msg;
 
@@ -583,7 +739,7 @@ static void w1_slave_detach(struct w1_slave *sl)
        msg.type = W1_SLAVE_REMOVE;
        w1_netlink_send(sl->master, &msg);
 
-       sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+       device_remove_file(&sl->dev, &w1_slave_attr_id);
        device_remove_file(&sl->dev, &w1_slave_attr_name);
        device_unregister(&sl->dev);
 
@@ -591,24 +747,6 @@ static void w1_slave_detach(struct w1_slave *sl)
        kfree(sl);
 }
 
-static struct w1_master *w1_search_master(void *data)
-{
-       struct w1_master *dev;
-       int found = 0;
-
-       mutex_lock(&w1_mlock);
-       list_for_each_entry(dev, &w1_masters, w1_master_entry) {
-               if (dev->bus_master->data == data) {
-                       found = 1;
-                       atomic_inc(&dev->refcnt);
-                       break;
-               }
-       }
-       mutex_unlock(&w1_mlock);
-
-       return (found)?dev:NULL;
-}
-
 struct w1_master *w1_search_master_id(u32 id)
 {
        struct w1_master *dev;
@@ -656,55 +794,56 @@ struct w1_slave *w1_search_slave(struct w1_reg_num *id)
        return (found)?sl:NULL;
 }
 
-void w1_reconnect_slaves(struct w1_family *f)
+void w1_reconnect_slaves(struct w1_family *f, int attach)
 {
+       struct w1_slave *sl, *sln;
        struct w1_master *dev;
 
        mutex_lock(&w1_mlock);
        list_for_each_entry(dev, &w1_masters, w1_master_entry) {
-               dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
-                               dev->name, f->fid);
-               set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
+               dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
+                       "for family %02x.\n", dev->name, f->fid);
+               mutex_lock(&dev->mutex);
+               list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
+                       /* If it is a new family, slaves with the default
+                        * family driver and are that family will be
+                        * connected.  If the family is going away, devices
+                        * matching that family are reconneced.
+                        */
+                       if ((attach && sl->family->fid == W1_FAMILY_DEFAULT
+                               && sl->reg_num.family == f->fid) ||
+                               (!attach && sl->family->fid == f->fid)) {
+                               struct w1_reg_num rn;
+
+                               memcpy(&rn, &sl->reg_num, sizeof(rn));
+                               w1_slave_detach(sl);
+
+                               w1_attach_slave_device(dev, &rn);
+                       }
+               }
+               dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
+                       "has been finished.\n", dev->name);
+               mutex_unlock(&dev->mutex);
        }
        mutex_unlock(&w1_mlock);
 }
 
-static void w1_slave_found(void *data, u64 rn)
+static void w1_slave_found(struct w1_master *dev, u64 rn)
 {
-       int slave_count;
        struct w1_slave *sl;
-       struct list_head *ent;
        struct w1_reg_num *tmp;
-       struct w1_master *dev;
        u64 rn_le = cpu_to_le64(rn);
 
-       dev = w1_search_master(data);
-       if (!dev) {
-               printk(KERN_ERR "Failed to find w1 master device for data %p, "
-                      "it is impossible.\n", data);
-               return;
-       }
+       atomic_inc(&dev->refcnt);
 
        tmp = (struct w1_reg_num *) &rn;
 
-       slave_count = 0;
-       list_for_each(ent, &dev->slist) {
-
-               sl = list_entry(ent, struct w1_slave, w1_slave_entry);
-
-               if (sl->reg_num.family == tmp->family &&
-                   sl->reg_num.id == tmp->id &&
-                   sl->reg_num.crc == tmp->crc) {
-                       set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
-                       break;
-               }
-
-               slave_count++;
-       }
-
-       if (slave_count == dev->slave_count &&
-               rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn_le, 7)) {
-               w1_attach_slave_device(dev, tmp);
+       sl = w1_slave_search_device(dev, tmp);
+       if (sl) {
+               set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
+       } else {
+               if (rn && tmp->crc == w1_calc_crc8((u8 *)&rn_le, 7))
+                       w1_attach_slave_device(dev, tmp);
        }
 
        atomic_dec(&dev->refcnt);
@@ -779,80 +918,20 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
                        /* extract the direction taken & update the device number */
                        tmp64 = (triplet_ret >> 2);
                        rn |= (tmp64 << i);
+
+                       if (kthread_should_stop()) {
+                               dev_dbg(&dev->dev, "Abort w1_search\n");
+                               return;
+                       }
                }
 
                if ( (triplet_ret & 0x03) != 0x03 ) {
                        if ( (desc_bit == last_zero) || (last_zero < 0))
                                last_device = 1;
                        desc_bit = last_zero;
-                       cb(dev->bus_master->data, rn);
-               }
-       }
-}
-
-static int w1_control(void *data)
-{
-       struct w1_slave *sl, *sln;
-       struct w1_master *dev, *n;
-       int have_to_wait = 0;
-
-       set_freezable();
-       while (!kthread_should_stop() || have_to_wait) {
-               have_to_wait = 0;
-
-               try_to_freeze();
-               msleep_interruptible(w1_control_timeout * 1000);
-
-               list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
-                       if (!kthread_should_stop() && !dev->flags)
-                               continue;
-                       /*
-                        * Little race: we can create thread but not set the flag.
-                        * Get a chance for external process to set flag up.
-                        */
-                       if (!dev->initialized) {
-                               have_to_wait = 1;
-                               continue;
-                       }
-
-                       if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
-                               set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
-
-                               mutex_lock(&w1_mlock);
-                               list_del(&dev->w1_master_entry);
-                               mutex_unlock(&w1_mlock);
-
-                               mutex_lock(&dev->mutex);
-                               list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
-                                       w1_slave_detach(sl);
-                               }
-                               w1_destroy_master_attributes(dev);
-                               mutex_unlock(&dev->mutex);
-                               atomic_dec(&dev->refcnt);
-                               continue;
-                       }
-
-                       if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
-                               dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
-                               mutex_lock(&dev->mutex);
-                               list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
-                                       if (sl->family->fid == W1_FAMILY_DEFAULT) {
-                                               struct w1_reg_num rn;
-
-                                               memcpy(&rn, &sl->reg_num, sizeof(rn));
-                                               w1_slave_detach(sl);
-
-                                               w1_attach_slave_device(dev, &rn);
-                                       }
-                               }
-                               dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
-                               clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
-                               mutex_unlock(&dev->mutex);
-                       }
+                       cb(dev, rn);
                }
        }
-
-       return 0;
 }
 
 void w1_search_process(struct w1_master *dev, u8 search_type)
@@ -878,23 +957,29 @@ void w1_search_process(struct w1_master *dev, u8 search_type)
 int w1_process(void *data)
 {
        struct w1_master *dev = (struct w1_master *) data;
+       /* As long as w1_timeout is only set by a module parameter the sleep
+        * time can be calculated in jiffies once.
+        */
+       const unsigned long jtime = msecs_to_jiffies(w1_timeout * 1000);
+
+       while (!kthread_should_stop()) {
+               if (dev->search_count) {
+                       mutex_lock(&dev->mutex);
+                       w1_search_process(dev, W1_SEARCH);
+                       mutex_unlock(&dev->mutex);
+               }
 
-       while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
                try_to_freeze();
-               msleep_interruptible(w1_timeout * 1000);
+               __set_current_state(TASK_INTERRUPTIBLE);
 
-               if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
+               if (kthread_should_stop())
                        break;
 
-               if (!dev->initialized)
-                       continue;
-
-               if (dev->search_count == 0)
-                       continue;
-
-               mutex_lock(&dev->mutex);
-               w1_search_process(dev, W1_SEARCH);
-               mutex_unlock(&dev->mutex);
+               /* Only sleep when the search is active. */
+               if (dev->search_count)
+                       schedule_timeout(jtime);
+               else
+                       schedule();
        }
 
        atomic_dec(&dev->refcnt);
@@ -932,18 +1017,13 @@ static int w1_init(void)
                goto err_out_master_unregister;
        }
 
-       w1_control_thread = kthread_run(w1_control, NULL, "w1_control");
-       if (IS_ERR(w1_control_thread)) {
-               retval = PTR_ERR(w1_control_thread);
-               printk(KERN_ERR "Failed to create control thread. err=%d\n",
-                       retval);
-               goto err_out_slave_unregister;
-       }
-
        return 0;
 
+#if 0
+/* For undoing the slave register if there was a step after it. */
 err_out_slave_unregister:
        driver_unregister(&w1_slave_driver);
+#endif
 
 err_out_master_unregister:
        driver_unregister(&w1_master_driver);
@@ -959,13 +1039,12 @@ static void w1_fini(void)
 {
        struct w1_master *dev;
 
+       /* Set netlink removal messages and some cleanup */
        list_for_each_entry(dev, &w1_masters, w1_master_entry)
                __w1_remove_master_device(dev);
 
        w1_fini_netlink();
 
-       kthread_stop(w1_control_thread);
-
        driver_unregister(&w1_slave_driver);
        driver_unregister(&w1_master_driver);
        bus_unregister(&w1_bus_type);
index f1df5343f4ad4a25ab87f7c1782216f1135eec33..cdaa6fffbfc73c2c6bd6be3eefdd2a600ca3f82e 100644 (file)
@@ -46,7 +46,6 @@ struct w1_reg_num
 #include "w1_family.h"
 
 #define W1_MAXNAMELEN          32
-#define W1_SLAVE_DATA_SIZE     128
 
 #define W1_SEARCH              0xF0
 #define W1_ALARM_SEARCH                0xEC
@@ -77,7 +76,7 @@ struct w1_slave
        struct completion       released;
 };
 
-typedef void (* w1_slave_found_callback)(void *, u64);
+typedef void (*w1_slave_found_callback)(struct w1_master *, u64);
 
 
 /**
@@ -142,12 +141,18 @@ struct w1_bus_master
         */
        u8              (*reset_bus)(void *);
 
-       /** Really nice hardware can handles the different types of ROM search */
-       void            (*search)(void *, u8, w1_slave_found_callback);
-};
+       /**
+        * Put out a strong pull-up pulse of the specified duration.
+        * @return -1=Error, 0=completed
+        */
+       u8              (*set_pullup)(void *, int);
 
-#define W1_MASTER_NEED_EXIT            0
-#define W1_MASTER_NEED_RECONNECT       1
+       /** Really nice hardware can handles the different types of ROM search
+        *  w1_master* is passed to the slave found callback.
+        */
+       void            (*search)(void *, struct w1_master *,
+               u8, w1_slave_found_callback);
+};
 
 struct w1_master
 {
@@ -167,7 +172,10 @@ struct w1_master
        void                    *priv;
        int                     priv_size;
 
-       long                    flags;
+       /** 5V strong pullup enabled flag, 1 enabled, zero disabled. */
+       int                     enable_pullup;
+       /** 5V strong pullup duration in milliseconds, zero disabled. */
+       int                     pullup_duration;
 
        struct task_struct      *thread;
        struct mutex            mutex;
@@ -181,12 +189,21 @@ struct w1_master
 };
 
 int w1_create_master_attributes(struct w1_master *);
+void w1_destroy_master_attributes(struct w1_master *master);
 void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb);
 void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb);
 struct w1_slave *w1_search_slave(struct w1_reg_num *id);
 void w1_search_process(struct w1_master *dev, u8 search_type);
 struct w1_master *w1_search_master_id(u32 id);
 
+/* Disconnect and reconnect devices in the given family.  Used for finding
+ * unclaimed devices after a family has been registered or releasing devices
+ * after a family has been unregistered.  Set attach to 1 when a new family
+ * has just been registered, to 0 when it has been unregistered.
+ */
+void w1_reconnect_slaves(struct w1_family *f, int attach);
+void w1_slave_detach(struct w1_slave *sl);
+
 u8 w1_triplet(struct w1_master *dev, int bdir);
 void w1_write_8(struct w1_master *, u8);
 int w1_reset_bus(struct w1_master *);
@@ -194,6 +211,7 @@ u8 w1_calc_crc8(u8 *, int);
 void w1_write_block(struct w1_master *, const u8 *, int);
 u8 w1_read_block(struct w1_master *, u8 *, int);
 int w1_reset_select_slave(struct w1_slave *sl);
+void w1_next_pullup(struct w1_master *, int);
 
 static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
 {
index a3c95bd6890af7ae20a8c63b00d3b0082f714ad0..4a099041f28a8a80a73b0d4d63da6be496efbdc8 100644 (file)
@@ -48,12 +48,12 @@ int w1_register_family(struct w1_family *newf)
 
        if (!ret) {
                atomic_set(&newf->refcnt, 0);
-               newf->need_exit = 0;
                list_add_tail(&newf->family_entry, &w1_families);
        }
        spin_unlock(&w1_flock);
 
-       w1_reconnect_slaves(newf);
+       /* check default devices against the new set of drivers */
+       w1_reconnect_slaves(newf, 1);
 
        return ret;
 }
@@ -72,11 +72,11 @@ void w1_unregister_family(struct w1_family *fent)
                        break;
                }
        }
-
-       fent->need_exit = 1;
-
        spin_unlock(&w1_flock);
 
+       /* deatch devices using this family code */
+       w1_reconnect_slaves(fent, 0);
+
        while (atomic_read(&fent->refcnt)) {
                printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n",
                                fent->fid, atomic_read(&fent->refcnt));
@@ -109,8 +109,7 @@ struct w1_family * w1_family_registered(u8 fid)
 
 static void __w1_family_put(struct w1_family *f)
 {
-       if (atomic_dec_and_test(&f->refcnt))
-               f->need_exit = 1;
+       atomic_dec(&f->refcnt);
 }
 
 void w1_family_put(struct w1_family *f)
index ef1e1dafa19a36c61a24d2fa126d9f9bd4cda118..3ca1b9298f2143dea98a2973021cdafe254bad38 100644 (file)
@@ -33,6 +33,7 @@
 #define W1_THERM_DS1822        0x22
 #define W1_EEPROM_DS2433       0x23
 #define W1_THERM_DS18B20       0x28
+#define W1_EEPROM_DS2431       0x2D
 #define W1_FAMILY_DS2760       0x30
 
 #define MAXNAMELEN             32
@@ -53,7 +54,6 @@ struct w1_family
        struct w1_family_ops    *fops;
 
        atomic_t                refcnt;
-       u8                      need_exit;
 };
 
 extern spinlock_t w1_flock;
@@ -63,6 +63,5 @@ void __w1_family_get(struct w1_family *);
 struct w1_family * w1_family_registered(u8);
 void w1_unregister_family(struct w1_family *);
 int w1_register_family(struct w1_family *);
-void w1_reconnect_slaves(struct w1_family *f);
 
 #endif /* __W1_FAMILY_H */
index 6840dfebe4d4c82a5abc242a8ee1d66570f100ab..a3a54567bfba87f041b8d0735aa7d96996a604d8 100644 (file)
 #include "w1_netlink.h"
 #include "w1_int.h"
 
-static u32 w1_ids = 1;
+static int w1_search_count = -1; /* Default is continual scan */
+module_param_named(search_count, w1_search_count, int, 0);
+
+static int w1_enable_pullup = 1;
+module_param_named(enable_pullup, w1_enable_pullup, int, 0);
 
 static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
                                       struct device_driver *driver,
@@ -59,8 +63,12 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
        dev->initialized        = 0;
        dev->id                 = id;
        dev->slave_ttl          = slave_ttl;
-        dev->search_count      = -1; /* continual scan */
+       dev->search_count       = w1_search_count;
+       dev->enable_pullup      = w1_enable_pullup;
 
+       /* 1 for w1_process to decrement
+        * 1 for __w1_remove_master_device to decrement
+        */
        atomic_set(&dev->refcnt, 2);
 
        INIT_LIST_HEAD(&dev->slist);
@@ -93,9 +101,10 @@ static void w1_free_dev(struct w1_master *dev)
 
 int w1_add_master_device(struct w1_bus_master *master)
 {
-       struct w1_master *dev;
+       struct w1_master *dev, *entry;
        int retval = 0;
        struct w1_netlink_msg msg;
+       int id, found;
 
         /* validate minimum functionality */
         if (!(master->touch_bit && master->reset_bus) &&
@@ -104,10 +113,50 @@ int w1_add_master_device(struct w1_bus_master *master)
                printk(KERN_ERR "w1_add_master_device: invalid function set\n");
                return(-EINVAL);
         }
+       /* While it would be electrically possible to make a device that
+        * generated a strong pullup in bit bang mode, only hardare that
+        * controls 1-wire time frames are even expected to support a strong
+        * pullup.  w1_io.c would need to support calling set_pullup before
+        * the last write_bit operation of a w1_write_8 which it currently
+        * doesn't.
+        */
+       if (!master->write_byte && !master->touch_bit && master->set_pullup) {
+               printk(KERN_ERR "w1_add_master_device: set_pullup requires "
+                       "write_byte or touch_bit, disabling\n");
+               master->set_pullup = NULL;
+       }
+
+       /* Lock until the device is added (or not) to w1_masters. */
+       mutex_lock(&w1_mlock);
+       /* Search for the first available id (starting at 1). */
+       id = 0;
+       do {
+               ++id;
+               found = 0;
+               list_for_each_entry(entry, &w1_masters, w1_master_entry) {
+                       if (entry->id == id) {
+                               found = 1;
+                               break;
+                       }
+               }
+       } while (found);
 
-       dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
-       if (!dev)
+       dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
+               &w1_master_driver, &w1_master_device);
+       if (!dev) {
+               mutex_unlock(&w1_mlock);
                return -ENOMEM;
+       }
+
+       retval =  w1_create_master_attributes(dev);
+       if (retval) {
+               mutex_unlock(&w1_mlock);
+               goto err_out_free_dev;
+       }
+
+       memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
+
+       dev->initialized = 1;
 
        dev->thread = kthread_run(&w1_process, dev, "%s", dev->name);
        if (IS_ERR(dev->thread)) {
@@ -115,18 +164,10 @@ int w1_add_master_device(struct w1_bus_master *master)
                dev_err(&dev->dev,
                         "Failed to create new kernel thread. err=%d\n",
                         retval);
-               goto err_out_free_dev;
+               mutex_unlock(&w1_mlock);
+               goto err_out_rm_attr;
        }
 
-       retval =  w1_create_master_attributes(dev);
-       if (retval)
-               goto err_out_kill_thread;
-
-       memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
-
-       dev->initialized = 1;
-
-       mutex_lock(&w1_mlock);
        list_add(&dev->w1_master_entry, &w1_masters);
        mutex_unlock(&w1_mlock);
 
@@ -137,8 +178,12 @@ int w1_add_master_device(struct w1_bus_master *master)
 
        return 0;
 
+#if 0 /* Thread cleanup code, not required currently. */
 err_out_kill_thread:
        kthread_stop(dev->thread);
+#endif
+err_out_rm_attr:
+       w1_destroy_master_attributes(dev);
 err_out_free_dev:
        w1_free_dev(dev);
 
@@ -148,10 +193,21 @@ err_out_free_dev:
 void __w1_remove_master_device(struct w1_master *dev)
 {
        struct w1_netlink_msg msg;
+       struct w1_slave *sl, *sln;
 
-       set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
        kthread_stop(dev->thread);
 
+       mutex_lock(&w1_mlock);
+       list_del(&dev->w1_master_entry);
+       mutex_unlock(&w1_mlock);
+
+       mutex_lock(&dev->mutex);
+       list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry)
+               w1_slave_detach(sl);
+       w1_destroy_master_attributes(dev);
+       mutex_unlock(&dev->mutex);
+       atomic_dec(&dev->refcnt);
+
        while (atomic_read(&dev->refcnt)) {
                dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
                                dev->name, atomic_read(&dev->refcnt));
index 30b6fbf83bd4a9fcead97864e679d6c7bd222d07..f4f82f1f486ebdd2c70c9ff80c5fdb4e99f03fe2 100644 (file)
@@ -92,6 +92,40 @@ static void w1_write_bit(struct w1_master *dev, int bit)
        }
 }
 
+/**
+ * Pre-write operation, currently only supporting strong pullups.
+ * Program the hardware for a strong pullup, if one has been requested and
+ * the hardware supports it.
+ *
+ * @param dev     the master device
+ */
+static void w1_pre_write(struct w1_master *dev)
+{
+       if (dev->pullup_duration &&
+               dev->enable_pullup && dev->bus_master->set_pullup) {
+               dev->bus_master->set_pullup(dev->bus_master->data,
+                       dev->pullup_duration);
+       }
+}
+
+/**
+ * Post-write operation, currently only supporting strong pullups.
+ * If a strong pullup was requested, clear it if the hardware supports
+ * them, or execute the delay otherwise, in either case clear the request.
+ *
+ * @param dev     the master device
+ */
+static void w1_post_write(struct w1_master *dev)
+{
+       if (dev->pullup_duration) {
+               if (dev->enable_pullup && dev->bus_master->set_pullup)
+                       dev->bus_master->set_pullup(dev->bus_master->data, 0);
+               else
+                       msleep(dev->pullup_duration);
+               dev->pullup_duration = 0;
+       }
+}
+
 /**
  * Writes 8 bits.
  *
@@ -102,11 +136,17 @@ void w1_write_8(struct w1_master *dev, u8 byte)
 {
        int i;
 
-       if (dev->bus_master->write_byte)
+       if (dev->bus_master->write_byte) {
+               w1_pre_write(dev);
                dev->bus_master->write_byte(dev->bus_master->data, byte);
+       }
        else
-               for (i = 0; i < 8; ++i)
+               for (i = 0; i < 8; ++i) {
+                       if (i == 7)
+                               w1_pre_write(dev);
                        w1_touch_bit(dev, (byte >> i) & 0x1);
+               }
+       w1_post_write(dev);
 }
 EXPORT_SYMBOL_GPL(w1_write_8);
 
@@ -203,11 +243,14 @@ void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
 {
        int i;
 
-       if (dev->bus_master->write_block)
+       if (dev->bus_master->write_block) {
+               w1_pre_write(dev);
                dev->bus_master->write_block(dev->bus_master->data, buf, len);
+       }
        else
                for (i = 0; i < len; ++i)
-                       w1_write_8(dev, buf[i]);
+                       w1_write_8(dev, buf[i]); /* calls w1_pre_write */
+       w1_post_write(dev);
 }
 EXPORT_SYMBOL_GPL(w1_write_block);
 
@@ -250,12 +293,24 @@ int w1_reset_bus(struct w1_master *dev)
                result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
        else {
                dev->bus_master->write_bit(dev->bus_master->data, 0);
+               /* minimum 480, max ? us
+                * be nice and sleep, except 18b20 spec lists 960us maximum,
+                * so until we can sleep with microsecond accuracy, spin.
+                * Feel free to come up with some other way to give up the
+                * cpu for such a short amount of time AND get it back in
+                * the maximum amount of time.
+                */
                w1_delay(480);
                dev->bus_master->write_bit(dev->bus_master->data, 1);
                w1_delay(70);
 
                result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1;
-               w1_delay(410);
+               /* minmum 70 (above) + 410 = 480 us
+                * There aren't any timing requirements between a reset and
+                * the following transactions.  Sleeping is safe here.
+                */
+               /* w1_delay(410); min required time */
+               msleep(1);
        }
 
        return result;
@@ -277,7 +332,8 @@ void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_cal
 {
        dev->attempts++;
        if (dev->bus_master->search)
-               dev->bus_master->search(dev->bus_master->data, search_type, cb);
+               dev->bus_master->search(dev->bus_master->data, dev,
+                       search_type, cb);
        else
                w1_search(dev, search_type, cb);
 }
@@ -305,3 +361,20 @@ int w1_reset_select_slave(struct w1_slave *sl)
        return 0;
 }
 EXPORT_SYMBOL_GPL(w1_reset_select_slave);
+
+/**
+ * Put out a strong pull-up of the specified duration after the next write
+ * operation.  Not all hardware supports strong pullups.  Hardware that
+ * doesn't support strong pullups will sleep for the given time after the
+ * write operation without a strong pullup.  This is a one shot request for
+ * the next write, specifying zero will clear a previous request.
+ * The w1 master lock must be held.
+ *
+ * @param delay        time in milliseconds
+ * @return     0=success, anything else=error
+ */
+void w1_next_pullup(struct w1_master *dev, int delay)
+{
+       dev->pullup_duration = delay;
+}
+EXPORT_SYMBOL_GPL(w1_next_pullup);
index 17c9c5ec14c526fe0eddbf77e9771550bae6fbb8..801db1341811d6eace2732c7238bfd9190ffff1f 100644 (file)
@@ -25,7 +25,7 @@ config BINFMT_ELF
 
 config COMPAT_BINFMT_ELF
        bool
-       depends on COMPAT && MMU
+       depends on COMPAT && BINFMT_ELF
 
 config BINFMT_ELF_FDPIC
        bool "Kernel support for FDPIC ELF binaries"
index b6f27dc26b7254a25c4dbf5223a2d24ce67f46d4..d0c69f57e5bfdebd65a668443428c44373360ab0 100644 (file)
@@ -8,7 +8,7 @@
 obj-y :=       open.o read_write.o file_table.o super.o \
                char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
                ioctl.o readdir.o select.o fifo.o dcache.o inode.o \
-               attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
+               attr.o bad_inode.o file.o filesystems.o namespace.o \
                seq_file.o xattr.o libfs.o fs-writeback.o \
                pnode.o drop_caches.o splice.o sync.o utimes.o \
                stack.o
@@ -27,6 +27,7 @@ obj-$(CONFIG_ANON_INODES)     += anon_inodes.o
 obj-$(CONFIG_SIGNALFD)         += signalfd.o
 obj-$(CONFIG_TIMERFD)          += timerfd.o
 obj-$(CONFIG_EVENTFD)          += eventfd.o
+obj-$(CONFIG_AIO)               += aio.o
 obj-$(CONFIG_FILE_LOCKING)      += locks.o
 obj-$(CONFIG_COMPAT)           += compat.o compat_ioctl.o
 
index 525f7c56e068d877e95dedea3a15dafc116fdb41..a3901769a96c4231b3b6c0cf88b9d3e6746f7468 100644 (file)
@@ -50,8 +50,8 @@ const struct address_space_operations afs_fs_aops = {
        .launder_page   = afs_launder_page,
        .releasepage    = afs_releasepage,
        .invalidatepage = afs_invalidatepage,
-       .prepare_write  = afs_prepare_write,
-       .commit_write   = afs_commit_write,
+       .write_begin    = afs_write_begin,
+       .write_end      = afs_write_end,
        .writepage      = afs_writepage,
        .writepages     = afs_writepages,
 };
index 3cb6920ff30bc6ee7f22a98a390b04119d1ae81c..67f259d99cd6f11afae3b9296b74f0f5bdde3065 100644 (file)
@@ -728,8 +728,12 @@ extern int afs_volume_release_fileserver(struct afs_vnode *,
  */
 extern int afs_set_page_dirty(struct page *);
 extern void afs_put_writeback(struct afs_writeback *);
-extern int afs_prepare_write(struct file *, struct page *, unsigned, unsigned);
-extern int afs_commit_write(struct file *, struct page *, unsigned, unsigned);
+extern int afs_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata);
+extern int afs_write_end(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+                       struct page *page, void *fsdata);
 extern int afs_writepage(struct page *, struct writeback_control *);
 extern int afs_writepages(struct address_space *, struct writeback_control *);
 extern int afs_write_inode(struct inode *, int);
index 065b4e10681ae2e449b700ad01c9d3f1c75cd9ab..d6b85dab35fcc71a16ba310bb11848c7ae7e891d 100644 (file)
@@ -84,15 +84,23 @@ void afs_put_writeback(struct afs_writeback *wb)
  * partly or wholly fill a page that's under preparation for writing
  */
 static int afs_fill_page(struct afs_vnode *vnode, struct key *key,
-                        unsigned start, unsigned len, struct page *page)
+                        loff_t pos, unsigned len, struct page *page)
 {
+       loff_t i_size;
+       unsigned eof;
        int ret;
 
-       _enter(",,%u,%u", start, len);
+       _enter(",,%llu,%u", (unsigned long long)pos, len);
 
-       ASSERTCMP(start + len, <=, PAGE_SIZE);
+       ASSERTCMP(len, <=, PAGE_CACHE_SIZE);
 
-       ret = afs_vnode_fetch_data(vnode, key, start, len, page);
+       i_size = i_size_read(&vnode->vfs_inode);
+       if (pos + len > i_size)
+               eof = i_size;
+       else
+               eof = PAGE_CACHE_SIZE;
+
+       ret = afs_vnode_fetch_data(vnode, key, 0, eof, page);
        if (ret < 0) {
                if (ret == -ENOENT) {
                        _debug("got NOENT from server"
@@ -106,110 +114,56 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key,
        return ret;
 }
 
-/*
- * prepare a page for being written to
- */
-static int afs_prepare_page(struct afs_vnode *vnode, struct page *page,
-                           struct key *key, unsigned offset, unsigned to)
-{
-       unsigned eof, tail, start, stop, len;
-       loff_t i_size, pos;
-       void *p;
-       int ret;
-
-       _enter("");
-
-       if (offset == 0 && to == PAGE_SIZE)
-               return 0;
-
-       p = kmap_atomic(page, KM_USER0);
-
-       i_size = i_size_read(&vnode->vfs_inode);
-       pos = (loff_t) page->index << PAGE_SHIFT;
-       if (pos >= i_size) {
-               /* partial write, page beyond EOF */
-               _debug("beyond");
-               if (offset > 0)
-                       memset(p, 0, offset);
-               if (to < PAGE_SIZE)
-                       memset(p + to, 0, PAGE_SIZE - to);
-               kunmap_atomic(p, KM_USER0);
-               return 0;
-       }
-
-       if (i_size - pos >= PAGE_SIZE) {
-               /* partial write, page entirely before EOF */
-               _debug("before");
-               tail = eof = PAGE_SIZE;
-       } else {
-               /* partial write, page overlaps EOF */
-               eof = i_size - pos;
-               _debug("overlap %u", eof);
-               tail = max(eof, to);
-               if (tail < PAGE_SIZE)
-                       memset(p + tail, 0, PAGE_SIZE - tail);
-               if (offset > eof)
-                       memset(p + eof, 0, PAGE_SIZE - eof);
-       }
-
-       kunmap_atomic(p, KM_USER0);
-
-       ret = 0;
-       if (offset > 0 || eof > to) {
-               /* need to fill one or two bits that aren't going to be written
-                * (cover both fillers in one read if there are two) */
-               start = (offset > 0) ? 0 : to;
-               stop = (eof > to) ? eof : offset;
-               len = stop - start;
-               _debug("wr=%u-%u av=0-%u rd=%u@%u",
-                      offset, to, eof, start, len);
-               ret = afs_fill_page(vnode, key, start, len, page);
-       }
-
-       _leave(" = %d", ret);
-       return ret;
-}
-
 /*
  * prepare to perform part of a write to a page
- * - the caller holds the page locked, preventing it from being written out or
- *   modified by anyone else
  */
-int afs_prepare_write(struct file *file, struct page *page,
-                     unsigned offset, unsigned to)
+int afs_write_begin(struct file *file, struct address_space *mapping,
+                   loff_t pos, unsigned len, unsigned flags,
+                   struct page **pagep, void **fsdata)
 {
        struct afs_writeback *candidate, *wb;
        struct afs_vnode *vnode = AFS_FS_I(file->f_dentry->d_inode);
+       struct page *page;
        struct key *key = file->private_data;
-       pgoff_t index;
+       unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+       unsigned to = from + len;
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
        int ret;
 
        _enter("{%x:%u},{%lx},%u,%u",
-              vnode->fid.vid, vnode->fid.vnode, page->index, offset, to);
+              vnode->fid.vid, vnode->fid.vnode, index, from, to);
 
        candidate = kzalloc(sizeof(*candidate), GFP_KERNEL);
        if (!candidate)
                return -ENOMEM;
        candidate->vnode = vnode;
-       candidate->first = candidate->last = page->index;
-       candidate->offset_first = offset;
+       candidate->first = candidate->last = index;
+       candidate->offset_first = from;
        candidate->to_last = to;
        candidate->usage = 1;
        candidate->state = AFS_WBACK_PENDING;
        init_waitqueue_head(&candidate->waitq);
 
+       page = __grab_cache_page(mapping, index);
+       if (!page) {
+               kfree(candidate);
+               return -ENOMEM;
+       }
+       *pagep = page;
+       /* page won't leak in error case: it eventually gets cleaned off LRU */
+
        if (!PageUptodate(page)) {
                _debug("not up to date");
-               ret = afs_prepare_page(vnode, page, key, offset, to);
+               ret = afs_fill_page(vnode, key, pos, len, page);
                if (ret < 0) {
                        kfree(candidate);
                        _leave(" = %d [prep]", ret);
                        return ret;
                }
+               SetPageUptodate(page);
        }
 
 try_again:
-       index = page->index;
        spin_lock(&vnode->writeback_lock);
 
        /* see if this page is already pending a writeback under a suitable key
@@ -242,8 +196,8 @@ try_again:
 subsume_in_current_wb:
        _debug("subsume");
        ASSERTRANGE(wb->first, <=, index, <=, wb->last);
-       if (index == wb->first && offset < wb->offset_first)
-               wb->offset_first = offset;
+       if (index == wb->first && from < wb->offset_first)
+               wb->offset_first = from;
        if (index == wb->last && to > wb->to_last)
                wb->to_last = to;
        spin_unlock(&vnode->writeback_lock);
@@ -289,17 +243,17 @@ flush_conflicting_wb:
 /*
  * finalise part of a write to a page
  */
-int afs_commit_write(struct file *file, struct page *page,
-                    unsigned offset, unsigned to)
+int afs_write_end(struct file *file, struct address_space *mapping,
+                 loff_t pos, unsigned len, unsigned copied,
+                 struct page *page, void *fsdata)
 {
        struct afs_vnode *vnode = AFS_FS_I(file->f_dentry->d_inode);
        loff_t i_size, maybe_i_size;
 
-       _enter("{%x:%u},{%lx},%u,%u",
-              vnode->fid.vid, vnode->fid.vnode, page->index, offset, to);
+       _enter("{%x:%u},{%lx}",
+              vnode->fid.vid, vnode->fid.vnode, page->index);
 
-       maybe_i_size = (loff_t) page->index << PAGE_SHIFT;
-       maybe_i_size += to;
+       maybe_i_size = pos + copied;
 
        i_size = i_size_read(&vnode->vfs_inode);
        if (maybe_i_size > i_size) {
@@ -310,12 +264,13 @@ int afs_commit_write(struct file *file, struct page *page,
                spin_unlock(&vnode->writeback_lock);
        }
 
-       SetPageUptodate(page);
        set_page_dirty(page);
        if (PageDirty(page))
                _debug("dirtied");
+       unlock_page(page);
+       page_cache_release(page);
 
-       return 0;
+       return copied;
 }
 
 /*
index f2c3b79e94d2be98f9535474ba34f86d1ebb5d92..a811c1f7d9abda7c2be12071a63e0b0502adeb2e 100644 (file)
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_AUTOFS4_FS) += autofs4.o
 
-autofs4-objs := init.o inode.o root.o symlink.o waitq.o expire.o
+autofs4-objs := init.o inode.o root.o symlink.o waitq.o expire.o dev-ioctl.o
index 69a2f5c9231943f6adbe4497915b294fe7991a28..e0f16da00e54294912bfd3a36fab3a09d0f1741f 100644 (file)
@@ -14,6 +14,7 @@
 /* Internal header file for autofs */
 
 #include <linux/auto_fs4.h>
+#include <linux/auto_dev-ioctl.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
 
 #define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY
 #define AUTOFS_IOC_COUNT     32
 
+#define AUTOFS_DEV_IOCTL_IOC_FIRST     (AUTOFS_DEV_IOCTL_VERSION)
+#define AUTOFS_DEV_IOCTL_IOC_COUNT     (AUTOFS_IOC_COUNT - 11)
+
+#define AUTOFS_TYPE_TRIGGER    (AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET)
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/time.h>
 /* #define DEBUG */
 
 #ifdef DEBUG
-#define DPRINTK(fmt,args...) do { printk(KERN_DEBUG "pid %d: %s: " fmt "\n" , current->pid , __func__ , ##args); } while(0)
+#define DPRINTK(fmt, args...)                          \
+do {                                                   \
+       printk(KERN_DEBUG "pid %d: %s: " fmt "\n",      \
+               current->pid, __func__, ##args);        \
+} while (0)
 #else
-#define DPRINTK(fmt,args...) do {} while(0)
+#define DPRINTK(fmt, args...) do {} while (0)
 #endif
 
+#define AUTOFS_WARN(fmt, args...)                      \
+do {                                                   \
+       printk(KERN_WARNING "pid %d: %s: " fmt "\n",    \
+               current->pid, __func__, ##args);        \
+} while (0)
+
+#define AUTOFS_ERROR(fmt, args...)                     \
+do {                                                   \
+       printk(KERN_ERR "pid %d: %s: " fmt "\n",        \
+               current->pid, __func__, ##args);        \
+} while (0)
+
 /* Unified info structure.  This is pointed to by both the dentry and
    inode structures.  Each file in the filesystem has an instance of this
    structure.  It holds a reference to the dentry, so dentries are never
@@ -61,6 +83,9 @@ struct autofs_info {
        unsigned long last_used;
        atomic_t count;
 
+       uid_t uid;
+       gid_t gid;
+
        mode_t  mode;
        size_t  size;
 
@@ -92,10 +117,6 @@ struct autofs_wait_queue {
 
 #define AUTOFS_SBI_MAGIC 0x6d4a556d
 
-#define AUTOFS_TYPE_INDIRECT     0x0001
-#define AUTOFS_TYPE_DIRECT       0x0002
-#define AUTOFS_TYPE_OFFSET       0x0004
-
 struct autofs_sb_info {
        u32 magic;
        int pipefd;
@@ -169,6 +190,17 @@ int autofs4_expire_run(struct super_block *, struct vfsmount *,
                        struct autofs_packet_expire __user *);
 int autofs4_expire_multi(struct super_block *, struct vfsmount *,
                        struct autofs_sb_info *, int __user *);
+struct dentry *autofs4_expire_direct(struct super_block *sb,
+                                    struct vfsmount *mnt,
+                                    struct autofs_sb_info *sbi, int how);
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
+                                      struct vfsmount *mnt,
+                                      struct autofs_sb_info *sbi, int how);
+
+/* Device node initialization */
+
+int autofs_dev_ioctl_init(void);
+void autofs_dev_ioctl_exit(void);
 
 /* Operations structures */
 
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
new file mode 100644 (file)
index 0000000..625abf5
--- /dev/null
@@ -0,0 +1,863 @@
+/*
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
+ * Copyright 2008 Ian Kent <raven@themaw.net>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ */
+
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/namei.h>
+#include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/sched.h>
+#include <linux/compat.h>
+#include <linux/syscalls.h>
+#include <linux/smp_lock.h>
+#include <linux/magic.h>
+#include <linux/dcache.h>
+#include <linux/uaccess.h>
+
+#include "autofs_i.h"
+
+/*
+ * This module implements an interface for routing autofs ioctl control
+ * commands via a miscellaneous device file.
+ *
+ * The alternate interface is needed because we need to be able open
+ * an ioctl file descriptor on an autofs mount that may be covered by
+ * another mount. This situation arises when starting automount(8)
+ * or other user space daemon which uses direct mounts or offset
+ * mounts (used for autofs lazy mount/umount of nested mount trees),
+ * which have been left busy at at service shutdown.
+ */
+
+#define AUTOFS_DEV_IOCTL_SIZE  sizeof(struct autofs_dev_ioctl)
+
+typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *,
+                       struct autofs_dev_ioctl *);
+
+static int check_name(const char *name)
+{
+       if (!strchr(name, '/'))
+               return -EINVAL;
+       return 0;
+}
+
+/*
+ * Check a string doesn't overrun the chunk of
+ * memory we copied from user land.
+ */
+static int invalid_str(char *str, void *end)
+{
+       while ((void *) str <= end)
+               if (!*str++)
+                       return 0;
+       return -EINVAL;
+}
+
+/*
+ * Check that the user compiled against correct version of autofs
+ * misc device code.
+ *
+ * As well as checking the version compatibility this always copies
+ * the kernel interface version out.
+ */
+static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param)
+{
+       int err = 0;
+
+       if ((AUTOFS_DEV_IOCTL_VERSION_MAJOR != param->ver_major) ||
+           (AUTOFS_DEV_IOCTL_VERSION_MINOR < param->ver_minor)) {
+               AUTOFS_WARN("ioctl control interface version mismatch: "
+                    "kernel(%u.%u), user(%u.%u), cmd(%d)",
+                    AUTOFS_DEV_IOCTL_VERSION_MAJOR,
+                    AUTOFS_DEV_IOCTL_VERSION_MINOR,
+                    param->ver_major, param->ver_minor, cmd);
+               err = -EINVAL;
+       }
+
+       /* Fill in the kernel version. */
+       param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
+       param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
+
+       return err;
+}
+
+/*
+ * Copy parameter control struct, including a possible path allocated
+ * at the end of the struct.
+ */
+static struct autofs_dev_ioctl *copy_dev_ioctl(struct autofs_dev_ioctl __user *in)
+{
+       struct autofs_dev_ioctl tmp, *ads;
+
+       if (copy_from_user(&tmp, in, sizeof(tmp)))
+               return ERR_PTR(-EFAULT);
+
+       if (tmp.size < sizeof(tmp))
+               return ERR_PTR(-EINVAL);
+
+       ads = kmalloc(tmp.size, GFP_KERNEL);
+       if (!ads)
+               return ERR_PTR(-ENOMEM);
+
+       if (copy_from_user(ads, in, tmp.size)) {
+               kfree(ads);
+               return ERR_PTR(-EFAULT);
+       }
+
+       return ads;
+}
+
+static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)
+{
+       kfree(param);
+       return;
+}
+
+/*
+ * Check sanity of parameter control fields and if a path is present
+ * check that it has a "/" and is terminated.
+ */
+static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
+{
+       int err = -EINVAL;
+
+       if (check_dev_ioctl_version(cmd, param)) {
+               AUTOFS_WARN("invalid device control module version "
+                    "supplied for cmd(0x%08x)", cmd);
+               goto out;
+       }
+
+       if (param->size > sizeof(*param)) {
+               err = check_name(param->path);
+               if (err) {
+                       AUTOFS_WARN("invalid path supplied for cmd(0x%08x)",
+                                   cmd);
+                       goto out;
+               }
+
+               err = invalid_str(param->path,
+                                (void *) ((size_t) param + param->size));
+               if (err) {
+                       AUTOFS_WARN("invalid path supplied for cmd(0x%08x)",
+                                   cmd);
+                       goto out;
+               }
+       }
+
+       err = 0;
+out:
+       return err;
+}
+
+/*
+ * Get the autofs super block info struct from the file opened on
+ * the autofs mount point.
+ */
+static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f)
+{
+       struct autofs_sb_info *sbi = NULL;
+       struct inode *inode;
+
+       if (f) {
+               inode = f->f_path.dentry->d_inode;
+               sbi = autofs4_sbi(inode->i_sb);
+       }
+       return sbi;
+}
+
+/* Return autofs module protocol version */
+static int autofs_dev_ioctl_protover(struct file *fp,
+                                    struct autofs_sb_info *sbi,
+                                    struct autofs_dev_ioctl *param)
+{
+       param->arg1 = sbi->version;
+       return 0;
+}
+
+/* Return autofs module protocol sub version */
+static int autofs_dev_ioctl_protosubver(struct file *fp,
+                                       struct autofs_sb_info *sbi,
+                                       struct autofs_dev_ioctl *param)
+{
+       param->arg1 = sbi->sub_version;
+       return 0;
+}
+
+/*
+ * Walk down the mount stack looking for an autofs mount that
+ * has the requested device number (aka. new_encode_dev(sb->s_dev).
+ */
+static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
+{
+       struct dentry *dentry;
+       struct inode *inode;
+       struct super_block *sb;
+       dev_t s_dev;
+       unsigned int err;
+
+       err = -ENOENT;
+
+       /* Lookup the dentry name at the base of our mount point */
+       dentry = d_lookup(nd->path.dentry, &nd->last);
+       if (!dentry)
+               goto out;
+
+       dput(nd->path.dentry);
+       nd->path.dentry = dentry;
+
+       /* And follow the mount stack looking for our autofs mount */
+       while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
+               inode = nd->path.dentry->d_inode;
+               if (!inode)
+                       break;
+
+               sb = inode->i_sb;
+               s_dev = new_encode_dev(sb->s_dev);
+               if (devno == s_dev) {
+                       if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
+                               err = 0;
+                               break;
+                       }
+               }
+       }
+out:
+       return err;
+}
+
+/*
+ * Walk down the mount stack looking for an autofs mount that
+ * has the requested mount type (ie. indirect, direct or offset).
+ */
+static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
+{
+       struct dentry *dentry;
+       struct autofs_info *ino;
+       unsigned int err;
+
+       err = -ENOENT;
+
+       /* Lookup the dentry name at the base of our mount point */
+       dentry = d_lookup(nd->path.dentry, &nd->last);
+       if (!dentry)
+               goto out;
+
+       dput(nd->path.dentry);
+       nd->path.dentry = dentry;
+
+       /* And follow the mount stack looking for our autofs mount */
+       while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
+               ino = autofs4_dentry_ino(nd->path.dentry);
+               if (ino && ino->sbi->type & type) {
+                       err = 0;
+                       break;
+               }
+       }
+out:
+       return err;
+}
+
+static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
+{
+       struct files_struct *files = current->files;
+       struct fdtable *fdt;
+
+       spin_lock(&files->file_lock);
+       fdt = files_fdtable(files);
+       BUG_ON(fdt->fd[fd] != NULL);
+       rcu_assign_pointer(fdt->fd[fd], file);
+       FD_SET(fd, fdt->close_on_exec);
+       spin_unlock(&files->file_lock);
+}
+
+
+/*
+ * Open a file descriptor on the autofs mount point corresponding
+ * to the given path and device number (aka. new_encode_dev(sb->s_dev)).
+ */
+static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
+{
+       struct file *filp;
+       struct nameidata nd;
+       int err, fd;
+
+       fd = get_unused_fd();
+       if (likely(fd >= 0)) {
+               /* Get nameidata of the parent directory */
+               err = path_lookup(path, LOOKUP_PARENT, &nd);
+               if (err)
+                       goto out;
+
+               /*
+                * Search down, within the parent, looking for an
+                * autofs super block that has the device number
+                * corresponding to the autofs fs we want to open.
+                */
+               err = autofs_dev_ioctl_find_super(&nd, devid);
+               if (err) {
+                       path_put(&nd.path);
+                       goto out;
+               }
+
+               filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
+               if (IS_ERR(filp)) {
+                       err = PTR_ERR(filp);
+                       goto out;
+               }
+
+               autofs_dev_ioctl_fd_install(fd, filp);
+       }
+
+       return fd;
+
+out:
+       put_unused_fd(fd);
+       return err;
+}
+
+/* Open a file descriptor on an autofs mount point */
+static int autofs_dev_ioctl_openmount(struct file *fp,
+                                     struct autofs_sb_info *sbi,
+                                     struct autofs_dev_ioctl *param)
+{
+       const char *path;
+       dev_t devid;
+       int err, fd;
+
+       /* param->path has already been checked */
+       if (!param->arg1)
+               return -EINVAL;
+
+       param->ioctlfd = -1;
+
+       path = param->path;
+       devid = param->arg1;
+
+       err = 0;
+       fd = autofs_dev_ioctl_open_mountpoint(path, devid);
+       if (unlikely(fd < 0)) {
+               err = fd;
+               goto out;
+       }
+
+       param->ioctlfd = fd;
+out:
+       return err;
+}
+
+/* Close file descriptor allocated above (user can also use close(2)). */
+static int autofs_dev_ioctl_closemount(struct file *fp,
+                                      struct autofs_sb_info *sbi,
+                                      struct autofs_dev_ioctl *param)
+{
+       return sys_close(param->ioctlfd);
+}
+
+/*
+ * Send "ready" status for an existing wait (either a mount or an expire
+ * request).
+ */
+static int autofs_dev_ioctl_ready(struct file *fp,
+                                 struct autofs_sb_info *sbi,
+                                 struct autofs_dev_ioctl *param)
+{
+       autofs_wqt_t token;
+
+       token = (autofs_wqt_t) param->arg1;
+       return autofs4_wait_release(sbi, token, 0);
+}
+
+/*
+ * Send "fail" status for an existing wait (either a mount or an expire
+ * request).
+ */
+static int autofs_dev_ioctl_fail(struct file *fp,
+                                struct autofs_sb_info *sbi,
+                                struct autofs_dev_ioctl *param)
+{
+       autofs_wqt_t token;
+       int status;
+
+       token = (autofs_wqt_t) param->arg1;
+       status = param->arg2 ? param->arg2 : -ENOENT;
+       return autofs4_wait_release(sbi, token, status);
+}
+
+/*
+ * Set the pipe fd for kernel communication to the daemon.
+ *
+ * Normally this is set at mount using an option but if we
+ * are reconnecting to a busy mount then we need to use this
+ * to tell the autofs mount about the new kernel pipe fd. In
+ * order to protect mounts against incorrectly setting the
+ * pipefd we also require that the autofs mount be catatonic.
+ *
+ * This also sets the process group id used to identify the
+ * controlling process (eg. the owning automount(8) daemon).
+ */
+static int autofs_dev_ioctl_setpipefd(struct file *fp,
+                                     struct autofs_sb_info *sbi,
+                                     struct autofs_dev_ioctl *param)
+{
+       int pipefd;
+       int err = 0;
+
+       if (param->arg1 == -1)
+               return -EINVAL;
+
+       pipefd = param->arg1;
+
+       mutex_lock(&sbi->wq_mutex);
+       if (!sbi->catatonic) {
+               mutex_unlock(&sbi->wq_mutex);
+               return -EBUSY;
+       } else {
+               struct file *pipe = fget(pipefd);
+               if (!pipe->f_op || !pipe->f_op->write) {
+                       err = -EPIPE;
+                       fput(pipe);
+                       goto out;
+               }
+               sbi->oz_pgrp = task_pgrp_nr(current);
+               sbi->pipefd = pipefd;
+               sbi->pipe = pipe;
+               sbi->catatonic = 0;
+       }
+out:
+       mutex_unlock(&sbi->wq_mutex);
+       return err;
+}
+
+/*
+ * Make the autofs mount point catatonic, no longer responsive to
+ * mount requests. Also closes the kernel pipe file descriptor.
+ */
+static int autofs_dev_ioctl_catatonic(struct file *fp,
+                                     struct autofs_sb_info *sbi,
+                                     struct autofs_dev_ioctl *param)
+{
+       autofs4_catatonic_mode(sbi);
+       return 0;
+}
+
+/* Set the autofs mount timeout */
+static int autofs_dev_ioctl_timeout(struct file *fp,
+                                   struct autofs_sb_info *sbi,
+                                   struct autofs_dev_ioctl *param)
+{
+       unsigned long timeout;
+
+       timeout = param->arg1;
+       param->arg1 = sbi->exp_timeout / HZ;
+       sbi->exp_timeout = timeout * HZ;
+       return 0;
+}
+
+/*
+ * Return the uid and gid of the last request for the mount
+ *
+ * When reconstructing an autofs mount tree with active mounts
+ * we need to re-connect to mounts that may have used the original
+ * process uid and gid (or string variations of them) for mount
+ * lookups within the map entry.
+ */
+static int autofs_dev_ioctl_requester(struct file *fp,
+                                     struct autofs_sb_info *sbi,
+                                     struct autofs_dev_ioctl *param)
+{
+       struct autofs_info *ino;
+       struct nameidata nd;
+       const char *path;
+       dev_t devid;
+       int err = -ENOENT;
+
+       if (param->size <= sizeof(*param)) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       path = param->path;
+       devid = sbi->sb->s_dev;
+
+       param->arg1 = param->arg2 = -1;
+
+       /* Get nameidata of the parent directory */
+       err = path_lookup(path, LOOKUP_PARENT, &nd);
+       if (err)
+               goto out;
+
+       err = autofs_dev_ioctl_find_super(&nd, devid);
+       if (err)
+               goto out_release;
+
+       ino = autofs4_dentry_ino(nd.path.dentry);
+       if (ino) {
+               err = 0;
+               autofs4_expire_wait(nd.path.dentry);
+               spin_lock(&sbi->fs_lock);
+               param->arg1 = ino->uid;
+               param->arg2 = ino->gid;
+               spin_unlock(&sbi->fs_lock);
+       }
+
+out_release:
+       path_put(&nd.path);
+out:
+       return err;
+}
+
+/*
+ * Call repeatedly until it returns -EAGAIN, meaning there's nothing
+ * more that can be done.
+ */
+static int autofs_dev_ioctl_expire(struct file *fp,
+                                  struct autofs_sb_info *sbi,
+                                  struct autofs_dev_ioctl *param)
+{
+       struct dentry *dentry;
+       struct vfsmount *mnt;
+       int err = -EAGAIN;
+       int how;
+
+       how = param->arg1;
+       mnt = fp->f_path.mnt;
+
+       if (sbi->type & AUTOFS_TYPE_TRIGGER)
+               dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how);
+       else
+               dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how);
+
+       if (dentry) {
+               struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+               /*
+                * This is synchronous because it makes the daemon a
+                * little easier
+               */
+               err = autofs4_wait(sbi, dentry, NFY_EXPIRE);
+
+               spin_lock(&sbi->fs_lock);
+               if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
+                       ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
+                       sbi->sb->s_root->d_mounted++;
+               }
+               ino->flags &= ~AUTOFS_INF_EXPIRING;
+               complete_all(&ino->expire_complete);
+               spin_unlock(&sbi->fs_lock);
+               dput(dentry);
+       }
+
+       return err;
+}
+
+/* Check if autofs mount point is in use */
+static int autofs_dev_ioctl_askumount(struct file *fp,
+                                     struct autofs_sb_info *sbi,
+                                     struct autofs_dev_ioctl *param)
+{
+       param->arg1 = 0;
+       if (may_umount(fp->f_path.mnt))
+               param->arg1 = 1;
+       return 0;
+}
+
+/*
+ * Check if the given path is a mountpoint.
+ *
+ * If we are supplied with the file descriptor of an autofs
+ * mount we're looking for a specific mount. In this case
+ * the path is considered a mountpoint if it is itself a
+ * mountpoint or contains a mount, such as a multi-mount
+ * without a root mount. In this case we return 1 if the
+ * path is a mount point and the super magic of the covering
+ * mount if there is one or 0 if it isn't a mountpoint.
+ *
+ * If we aren't supplied with a file descriptor then we
+ * lookup the nameidata of the path and check if it is the
+ * root of a mount. If a type is given we are looking for
+ * a particular autofs mount and if we don't find a match
+ * we return fail. If the located nameidata path is the
+ * root of a mount we return 1 along with the super magic
+ * of the mount or 0 otherwise.
+ *
+ * In both cases the the device number (as returned by
+ * new_encode_dev()) is also returned.
+ */
+static int autofs_dev_ioctl_ismountpoint(struct file *fp,
+                                        struct autofs_sb_info *sbi,
+                                        struct autofs_dev_ioctl *param)
+{
+       struct nameidata nd;
+       const char *path;
+       unsigned int type;
+       int err = -ENOENT;
+
+       if (param->size <= sizeof(*param)) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       path = param->path;
+       type = param->arg1;
+
+       param->arg1 = 0;
+       param->arg2 = 0;
+
+       if (!fp || param->ioctlfd == -1) {
+               if (type == AUTOFS_TYPE_ANY) {
+                       struct super_block *sb;
+
+                       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+                       if (err)
+                               goto out;
+
+                       sb = nd.path.dentry->d_sb;
+                       param->arg1 = new_encode_dev(sb->s_dev);
+               } else {
+                       struct autofs_info *ino;
+
+                       err = path_lookup(path, LOOKUP_PARENT, &nd);
+                       if (err)
+                               goto out;
+
+                       err = autofs_dev_ioctl_find_sbi_type(&nd, type);
+                       if (err)
+                               goto out_release;
+
+                       ino = autofs4_dentry_ino(nd.path.dentry);
+                       param->arg1 = autofs4_get_dev(ino->sbi);
+               }
+
+               err = 0;
+               if (nd.path.dentry->d_inode &&
+                   nd.path.mnt->mnt_root == nd.path.dentry) {
+                       err = 1;
+                       param->arg2 = nd.path.dentry->d_inode->i_sb->s_magic;
+               }
+       } else {
+               dev_t devid = new_encode_dev(sbi->sb->s_dev);
+
+               err = path_lookup(path, LOOKUP_PARENT, &nd);
+               if (err)
+                       goto out;
+
+               err = autofs_dev_ioctl_find_super(&nd, devid);
+               if (err)
+                       goto out_release;
+
+               param->arg1 = autofs4_get_dev(sbi);
+
+               err = have_submounts(nd.path.dentry);
+
+               if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) {
+                       if (follow_down(&nd.path.mnt, &nd.path.dentry)) {
+                               struct inode *inode = nd.path.dentry->d_inode;
+                               param->arg2 = inode->i_sb->s_magic;
+                       }
+               }
+       }
+
+out_release:
+       path_put(&nd.path);
+out:
+       return err;
+}
+
+/*
+ * Our range of ioctl numbers isn't 0 based so we need to shift
+ * the array index by _IOC_NR(AUTOFS_CTL_IOC_FIRST) for the table
+ * lookup.
+ */
+#define cmd_idx(cmd)   (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST))
+
+static ioctl_fn lookup_dev_ioctl(unsigned int cmd)
+{
+       static struct {
+               int cmd;
+               ioctl_fn fn;
+       } _ioctls[] = {
+               {cmd_idx(AUTOFS_DEV_IOCTL_VERSION_CMD), NULL},
+               {cmd_idx(AUTOFS_DEV_IOCTL_PROTOVER_CMD),
+                        autofs_dev_ioctl_protover},
+               {cmd_idx(AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD),
+                        autofs_dev_ioctl_protosubver},
+               {cmd_idx(AUTOFS_DEV_IOCTL_OPENMOUNT_CMD),
+                        autofs_dev_ioctl_openmount},
+               {cmd_idx(AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD),
+                        autofs_dev_ioctl_closemount},
+               {cmd_idx(AUTOFS_DEV_IOCTL_READY_CMD),
+                        autofs_dev_ioctl_ready},
+               {cmd_idx(AUTOFS_DEV_IOCTL_FAIL_CMD),
+                        autofs_dev_ioctl_fail},
+               {cmd_idx(AUTOFS_DEV_IOCTL_SETPIPEFD_CMD),
+                        autofs_dev_ioctl_setpipefd},
+               {cmd_idx(AUTOFS_DEV_IOCTL_CATATONIC_CMD),
+                        autofs_dev_ioctl_catatonic},
+               {cmd_idx(AUTOFS_DEV_IOCTL_TIMEOUT_CMD),
+                        autofs_dev_ioctl_timeout},
+               {cmd_idx(AUTOFS_DEV_IOCTL_REQUESTER_CMD),
+                        autofs_dev_ioctl_requester},
+               {cmd_idx(AUTOFS_DEV_IOCTL_EXPIRE_CMD),
+                        autofs_dev_ioctl_expire},
+               {cmd_idx(AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD),
+                        autofs_dev_ioctl_askumount},
+               {cmd_idx(AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD),
+                        autofs_dev_ioctl_ismountpoint}
+       };
+       unsigned int idx = cmd_idx(cmd);
+
+       return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx].fn;
+}
+
+/* ioctl dispatcher */
+static int _autofs_dev_ioctl(unsigned int command, struct autofs_dev_ioctl __user *user)
+{
+       struct autofs_dev_ioctl *param;
+       struct file *fp;
+       struct autofs_sb_info *sbi;
+       unsigned int cmd_first, cmd;
+       ioctl_fn fn = NULL;
+       int err = 0;
+
+       /* only root can play with this */
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);
+       cmd = _IOC_NR(command);
+
+       if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) ||
+           cmd - cmd_first >= AUTOFS_DEV_IOCTL_IOC_COUNT) {
+               return -ENOTTY;
+       }
+
+       /* Copy the parameters into kernel space. */
+       param = copy_dev_ioctl(user);
+       if (IS_ERR(param))
+               return PTR_ERR(param);
+
+       err = validate_dev_ioctl(command, param);
+       if (err)
+               goto out;
+
+       /* The validate routine above always sets the version */
+       if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD)
+               goto done;
+
+       fn = lookup_dev_ioctl(cmd);
+       if (!fn) {
+               AUTOFS_WARN("unknown command 0x%08x", command);
+               return -ENOTTY;
+       }
+
+       fp = NULL;
+       sbi = NULL;
+
+       /*
+        * For obvious reasons the openmount can't have a file
+        * descriptor yet. We don't take a reference to the
+        * file during close to allow for immediate release.
+        */
+       if (cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&
+           cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {
+               fp = fget(param->ioctlfd);
+               if (!fp) {
+                       if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)
+                               goto cont;
+                       err = -EBADF;
+                       goto out;
+               }
+
+               if (!fp->f_op) {
+                       err = -ENOTTY;
+                       fput(fp);
+                       goto out;
+               }
+
+               sbi = autofs_dev_ioctl_sbi(fp);
+               if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) {
+                       err = -EINVAL;
+                       fput(fp);
+                       goto out;
+               }
+
+               /*
+                * Admin needs to be able to set the mount catatonic in
+                * order to be able to perform the re-open.
+                */
+               if (!autofs4_oz_mode(sbi) &&
+                   cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) {
+                       err = -EACCES;
+                       fput(fp);
+                       goto out;
+               }
+       }
+cont:
+       err = fn(fp, sbi, param);
+
+       if (fp)
+               fput(fp);
+done:
+       if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))
+               err = -EFAULT;
+out:
+       free_dev_ioctl(param);
+       return err;
+}
+
+static long autofs_dev_ioctl(struct file *file, uint command, ulong u)
+{
+       int err;
+       err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u);
+       return (long) err;
+}
+
+#ifdef CONFIG_COMPAT
+static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u)
+{
+       return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u));
+}
+#else
+#define autofs_dev_ioctl_compat NULL
+#endif
+
+static const struct file_operations _dev_ioctl_fops = {
+       .unlocked_ioctl  = autofs_dev_ioctl,
+       .compat_ioctl = autofs_dev_ioctl_compat,
+       .owner   = THIS_MODULE,
+};
+
+static struct miscdevice _autofs_dev_ioctl_misc = {
+       .minor          = MISC_DYNAMIC_MINOR,
+       .name           = AUTOFS_DEVICE_NAME,
+       .fops           = &_dev_ioctl_fops
+};
+
+/* Register/deregister misc character device */
+int autofs_dev_ioctl_init(void)
+{
+       int r;
+
+       r = misc_register(&_autofs_dev_ioctl_misc);
+       if (r) {
+               AUTOFS_ERROR("misc_register failed for control device");
+               return r;
+       }
+
+       return 0;
+}
+
+void autofs_dev_ioctl_exit(void)
+{
+       misc_deregister(&_autofs_dev_ioctl_misc);
+       return;
+}
+
index cdabb796ff018aa65eb20c4d6ec034613ab8e1c8..cde2f8e8935a680bd62243dcc4b92f6909ea7789 100644 (file)
@@ -244,10 +244,10 @@ cont:
 }
 
 /* Check if we can expire a direct mount (possibly a tree) */
-static struct dentry *autofs4_expire_direct(struct super_block *sb,
-                                           struct vfsmount *mnt,
-                                           struct autofs_sb_info *sbi,
-                                           int how)
+struct dentry *autofs4_expire_direct(struct super_block *sb,
+                                    struct vfsmount *mnt,
+                                    struct autofs_sb_info *sbi,
+                                    int how)
 {
        unsigned long timeout;
        struct dentry *root = dget(sb->s_root);
@@ -283,10 +283,10 @@ static struct dentry *autofs4_expire_direct(struct super_block *sb,
  *  - it is unused by any user process
  *  - it has been unused for exp_timeout time
  */
-static struct dentry *autofs4_expire_indirect(struct super_block *sb,
-                                             struct vfsmount *mnt,
-                                             struct autofs_sb_info *sbi,
-                                             int how)
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
+                                      struct vfsmount *mnt,
+                                      struct autofs_sb_info *sbi,
+                                      int how)
 {
        unsigned long timeout;
        struct dentry *root = sb->s_root;
@@ -479,7 +479,7 @@ int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
        if (arg && get_user(do_now, arg))
                return -EFAULT;
 
-       if (sbi->type & AUTOFS_TYPE_DIRECT)
+       if (sbi->type & AUTOFS_TYPE_TRIGGER)
                dentry = autofs4_expire_direct(sb, mnt, sbi, do_now);
        else
                dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
index 723a1c5e361b2786c8f8ec97e9332b77b1484e15..9722e4bd895725f42361b86d74355c3c4656bfbe 100644 (file)
@@ -29,11 +29,20 @@ static struct file_system_type autofs_fs_type = {
 
 static int __init init_autofs4_fs(void)
 {
-       return register_filesystem(&autofs_fs_type);
+       int err;
+
+       err = register_filesystem(&autofs_fs_type);
+       if (err)
+               return err;
+
+       autofs_dev_ioctl_init();
+
+       return err;
 }
 
 static void __exit exit_autofs4_fs(void)
 {
+       autofs_dev_ioctl_exit();
        unregister_filesystem(&autofs_fs_type);
 }
 
index 45d55819203d5f00cc5d9150bc81d7bdd63ca38a..c7e65bb30ba02b600e1b51d30e11ce78246ef983 100644 (file)
@@ -53,6 +53,8 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
                atomic_set(&ino->count, 0);
        }
 
+       ino->uid = 0;
+       ino->gid = 0;
        ino->mode = mode;
        ino->last_used = jiffies;
 
@@ -288,7 +290,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
                        *type = AUTOFS_TYPE_DIRECT;
                        break;
                case Opt_offset:
-                       *type = AUTOFS_TYPE_DIRECT | AUTOFS_TYPE_OFFSET;
+                       *type = AUTOFS_TYPE_OFFSET;
                        break;
                default:
                        return 1;
@@ -336,7 +338,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
        sbi->sb = s;
        sbi->version = 0;
        sbi->sub_version = 0;
-       sbi->type = 0;
+       sbi->type = AUTOFS_TYPE_INDIRECT;
        sbi->min_proto = 0;
        sbi->max_proto = 0;
        mutex_init(&sbi->wq_mutex);
@@ -378,7 +380,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
        }
 
        root_inode->i_fop = &autofs4_root_operations;
-       root_inode->i_op = sbi->type & AUTOFS_TYPE_DIRECT ?
+       root_inode->i_op = sbi->type & AUTOFS_TYPE_TRIGGER ?
                        &autofs4_direct_root_inode_operations :
                        &autofs4_indirect_root_inode_operations;
 
index 35216d18d8b56fa5a6b0ff8f07f37771698a0b75..4b67c2a2d77c51fcc93193dbdd6e31dea2defc14 100644 (file)
@@ -337,7 +337,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                 * is very similar for indirect mounts except only dentrys
                 * in the root of the autofs file system may be negative.
                 */
-               if (sbi->type & (AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET))
+               if (sbi->type & AUTOFS_TYPE_TRIGGER)
                        return -ENOENT;
                else if (!IS_ROOT(dentry->d_parent))
                        return -ENOENT;
@@ -348,7 +348,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                return -ENOMEM;
 
        /* If this is a direct mount request create a dummy name */
-       if (IS_ROOT(dentry) && (sbi->type & AUTOFS_TYPE_DIRECT))
+       if (IS_ROOT(dentry) && sbi->type & AUTOFS_TYPE_TRIGGER)
                qstr.len = sprintf(name, "%p", dentry);
        else {
                qstr.len = autofs4_getpath(sbi, dentry, &name);
@@ -406,11 +406,11 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                                type = autofs_ptype_expire_multi;
                } else {
                        if (notify == NFY_MOUNT)
-                               type = (sbi->type & AUTOFS_TYPE_DIRECT) ?
+                               type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
                                        autofs_ptype_missing_direct :
                                         autofs_ptype_missing_indirect;
                        else
-                               type = (sbi->type & AUTOFS_TYPE_DIRECT) ?
+                               type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
                                        autofs_ptype_expire_direct :
                                        autofs_ptype_expire_indirect;
                }
@@ -457,6 +457,40 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
 
        status = wq->status;
 
+       /*
+        * For direct and offset mounts we need to track the requester's
+        * uid and gid in the dentry info struct. This is so it can be
+        * supplied, on request, by the misc device ioctl interface.
+        * This is needed during daemon resatart when reconnecting
+        * to existing, active, autofs mounts. The uid and gid (and
+        * related string values) may be used for macro substitution
+        * in autofs mount maps.
+        */
+       if (!status) {
+               struct autofs_info *ino;
+               struct dentry *de = NULL;
+
+               /* direct mount or browsable map */
+               ino = autofs4_dentry_ino(dentry);
+               if (!ino) {
+                       /* If not lookup actual dentry used */
+                       de = d_lookup(dentry->d_parent, &dentry->d_name);
+                       if (de)
+                               ino = autofs4_dentry_ino(de);
+               }
+
+               /* Set mount requester */
+               if (ino) {
+                       spin_lock(&sbi->fs_lock);
+                       ino->uid = wq->uid;
+                       ino->gid = wq->gid;
+                       spin_unlock(&sbi->fs_lock);
+               }
+
+               if (de)
+                       dput(de);
+       }
+
        /* Are we the last process to need status? */
        mutex_lock(&sbi->wq_mutex);
        if (!--wq->wait_ctr)
index e2595c2c403a9bfd01dffc1ac54594356e09e811..7893eaa1e58c695d1cff286c0df64c3647b11e8e 100644 (file)
@@ -55,8 +55,12 @@ enum super_flags {
 };
 
 #define BEFS_BYTEORDER_NATIVE 0x42494745
+#define BEFS_BYTEORDER_NATIVE_LE (__force fs32)cpu_to_le32(BEFS_BYTEORDER_NATIVE)
+#define BEFS_BYTEORDER_NATIVE_BE (__force fs32)cpu_to_be32(BEFS_BYTEORDER_NATIVE)
 
 #define BEFS_SUPER_MAGIC BEFS_SUPER_MAGIC1
+#define BEFS_SUPER_MAGIC1_LE (__force fs32)cpu_to_le32(BEFS_SUPER_MAGIC1)
+#define BEFS_SUPER_MAGIC1_BE (__force fs32)cpu_to_be32(BEFS_SUPER_MAGIC1)
 
 /*
  * Flags of inode
index 9286b2af893a166768bcb43252ba8df7720f13e3..b6dfee37c7b71776201aa320ac6e450e00290cd7 100644 (file)
@@ -809,8 +809,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
 
        /* account for offset of super block on x86 */
        disk_sb = (befs_super_block *) bh->b_data;
-       if ((le32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1) ||
-           (be32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1)) {
+       if ((disk_sb->magic1 == BEFS_SUPER_MAGIC1_LE) ||
+           (disk_sb->magic1 == BEFS_SUPER_MAGIC1_BE)) {
                befs_debug(sb, "Using PPC superblock location");
        } else {
                befs_debug(sb, "Using x86 superblock location");
index 8c3401ff6d6a2a50013423feedff544b2f946f14..41f2b4d0093e66ed67ab747831cea76fedc397cb 100644 (file)
@@ -26,10 +26,10 @@ befs_load_sb(struct super_block *sb, befs_super_block * disk_sb)
        befs_sb_info *befs_sb = BEFS_SB(sb);
 
        /* Check the byte order of the filesystem */
-       if (le32_to_cpu(disk_sb->fs_byte_order) == BEFS_BYTEORDER_NATIVE)
+       if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE)
            befs_sb->byte_order = BEFS_BYTESEX_LE;
-       else if (be32_to_cpu(disk_sb->fs_byte_order) == BEFS_BYTEORDER_NATIVE)
-           befs_sb->byte_order = BEFS_BYTESEX_BE;      
+       else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE)
+           befs_sb->byte_order = BEFS_BYTESEX_BE;
 
        befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1);
        befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2);
index 655ed8d30a86ef7e963414a9cb56d6ed7dc5d3c4..c76afa26edf735c7644e32b931ac675cbbf08454 100644 (file)
@@ -683,7 +683,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                         * switch really is going to happen - do this in
                         * flush_thread().      - akpm
                         */
-                       SET_PERSONALITY(loc->elf_ex, 0);
+                       SET_PERSONALITY(loc->elf_ex);
 
                        interpreter = open_exec(elf_interpreter);
                        retval = PTR_ERR(interpreter);
@@ -734,7 +734,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                        goto out_free_dentry;
        } else {
                /* Executables without an interpreter also need a personality  */
-               SET_PERSONALITY(loc->elf_ex, 0);
+               SET_PERSONALITY(loc->elf_ex);
        }
 
        /* Flush all traces of the currently running executable */
@@ -748,7 +748,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 
        /* Do this immediately, since STACK_TOP as used in setup_arg_pages
           may depend on the personality.  */
-       SET_PERSONALITY(loc->elf_ex, 0);
+       SET_PERSONALITY(loc->elf_ex);
        if (elf_read_implies_exec(loc->elf_ex, executable_stack))
                current->personality |= READ_IMPLIES_EXEC;
 
index 80c1f952ef7814fc36b099457c6ab11c670c1884..0e8367c546248987418191c6ab7b14c5be61bec9 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/fcntl.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/security.h>
 #include <linux/highmem.h>
 #include <linux/highuid.h>
 #include <linux/personality.h>
@@ -455,8 +456,19 @@ error_kill:
 }
 
 /*****************************************************************************/
+
+#ifndef ELF_BASE_PLATFORM
 /*
- * present useful information to the program
+ * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
+ * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
+ * will be copied to the user stack in the same manner as AT_PLATFORM.
+ */
+#define ELF_BASE_PLATFORM NULL
+#endif
+
+/*
+ * present useful information to the program by shovelling it onto the new
+ * process's stack
  */
 static int create_elf_fdpic_tables(struct linux_binprm *bprm,
                                   struct mm_struct *mm,
@@ -466,15 +478,19 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
        unsigned long sp, csp, nitems;
        elf_caddr_t __user *argv, *envp;
        size_t platform_len = 0, len;
-       char *k_platform;
-       char __user *u_platform, *p;
+       char *k_platform, *k_base_platform;
+       char __user *u_platform, *u_base_platform, *p;
        long hwcap;
        int loop;
        int nr; /* reset for each csp adjustment */
 
-       /* we're going to shovel a whole load of stuff onto the stack */
 #ifdef CONFIG_MMU
-       sp = bprm->p;
+       /* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
+        * by the processes running on the same package. One thing we can do is
+        * to shuffle the initial stack for them, so we give the architecture
+        * an opportunity to do so here.
+        */
+       sp = arch_align_stack(bprm->p);
 #else
        sp = mm->start_stack;
 
@@ -483,11 +499,14 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
                return -EFAULT;
 #endif
 
-       /* get hold of platform and hardware capabilities masks for the machine
-        * we are running on.  In some cases (Sparc), this info is impossible
-        * to get, in others (i386) it is merely difficult.
-        */
        hwcap = ELF_HWCAP;
+
+       /*
+        * If this architecture has a platform capability string, copy it
+        * to userspace.  In some cases (Sparc), this info is impossible
+        * for userspace to get any other way, in others (i386) it is
+        * merely difficult.
+        */
        k_platform = ELF_PLATFORM;
        u_platform = NULL;
 
@@ -499,19 +518,20 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
                        return -EFAULT;
        }
 
-#if defined(__i386__) && defined(CONFIG_SMP)
-       /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
-        * by the processes running on the same package. One thing we can do is
-        * to shuffle the initial stack for them.
-        *
-        * the conditionals here are unneeded, but kept in to make the code
-        * behaviour the same as pre change unless we have hyperthreaded
-        * processors. This keeps Mr Marcelo Person happier but should be
-        * removed for 2.5
+       /*
+        * If this architecture has a "base" platform capability
+        * string, copy it to userspace.
         */
-       if (smp_num_siblings > 1)
-               sp = sp - ((current->pid % 64) << 7);
-#endif
+       k_base_platform = ELF_BASE_PLATFORM;
+       u_base_platform = NULL;
+
+       if (k_base_platform) {
+               platform_len = strlen(k_base_platform) + 1;
+               sp -= platform_len;
+               u_base_platform = (char __user *) sp;
+               if (__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
+                       return -EFAULT;
+       }
 
        sp &= ~7UL;
 
@@ -541,9 +561,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
        }
 
        /* force 16 byte _final_ alignment here for generality */
-#define DLINFO_ITEMS 13
+#define DLINFO_ITEMS 15
+
+       nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) +
+               (k_base_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
 
-       nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
+       if (bprm->interp_flags & BINPRM_FLAGS_EXECFD)
+               nitems++;
 
        csp = sp;
        sp -= nitems * 2 * sizeof(unsigned long);
@@ -575,6 +599,19 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
                            (elf_addr_t) (unsigned long) u_platform);
        }
 
+       if (k_base_platform) {
+               nr = 0;
+               csp -= 2 * sizeof(unsigned long);
+               NEW_AUX_ENT(AT_BASE_PLATFORM,
+                           (elf_addr_t) (unsigned long) u_base_platform);
+       }
+
+       if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
+               nr = 0;
+               csp -= 2 * sizeof(unsigned long);
+               NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
+       }
+
        nr = 0;
        csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
        NEW_AUX_ENT(AT_HWCAP,   hwcap);
@@ -590,6 +627,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
        NEW_AUX_ENT(AT_EUID,    (elf_addr_t) current->euid);
        NEW_AUX_ENT(AT_GID,     (elf_addr_t) current->gid);
        NEW_AUX_ENT(AT_EGID,    (elf_addr_t) current->egid);
+       NEW_AUX_ENT(AT_SECURE,  security_bprm_secureexec(bprm));
+       NEW_AUX_ENT(AT_EXECFN,  bprm->exec);
 
 #ifdef ARCH_DLINFO
        nr = 0;
index f9c88d0c8cedeabcfdca1a5f81a51e1e293a59ea..32fb00b52cd069ed600d9c1a925f2b831621325e 100644 (file)
@@ -43,7 +43,7 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
                        return -ENOEXEC;
        }
 
-       bprm->sh_bang = 1;      /* Well, the bang-shell is implicit... */
+       bprm->recursion_depth++; /* Well, the bang-shell is implicit... */
        allow_write_access(bprm->file);
        fput(bprm->file);
        bprm->file = NULL;
index dfc0197905ca1e9d50ce8ff613261b141d6f8439..ccb781a6a804121e17e317372eb852243303d687 100644 (file)
@@ -229,13 +229,13 @@ static int decompress_exec(
        ret = 10;
        if (buf[3] & EXTRA_FIELD) {
                ret += 2 + buf[10] + (buf[11] << 8);
-               if (unlikely(LBUFSIZE == ret)) {
+               if (unlikely(LBUFSIZE <= ret)) {
                        DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n");
                        goto out_free_buf;
                }
        }
        if (buf[3] & ORIG_NAME) {
-               for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
+               while (ret < LBUFSIZE && buf[ret++] != 0)
                        ;
                if (unlikely(LBUFSIZE == ret)) {
                        DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n");
@@ -243,7 +243,7 @@ static int decompress_exec(
                }
        }
        if (buf[3] & COMMENT) {
-               for (;  ret < LBUFSIZE && (buf[ret] != 0); ret++)
+               while (ret < LBUFSIZE && buf[ret++] != 0)
                        ;
                if (unlikely(LBUFSIZE == ret)) {
                        DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n");
index 8d7e88e02e0f9cc13207d86ee090a2594f79497b..f2744ab4e5b35c415724034f3f5a3a328997cf99 100644 (file)
@@ -117,7 +117,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                goto _ret;
 
        retval = -ENOEXEC;
-       if (bprm->misc_bang)
+       if (bprm->recursion_depth > BINPRM_MAX_RECURSION)
                goto _ret;
 
        /* to keep locking time low, we copy the interpreter string */
@@ -197,7 +197,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        if (retval < 0)
                goto _error;
 
-       bprm->misc_bang = 1;
+       bprm->recursion_depth++;
 
        retval = search_binary_handler (bprm, regs);
        if (retval < 0)
index 9e3963f7ebf19f85a1742ff034bbb518d51a6aff..08343505e18455dedebace59a8c489ecb3b1cf7a 100644 (file)
@@ -22,14 +22,15 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
        char interp[BINPRM_BUF_SIZE];
        int retval;
 
-       if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
+       if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') ||
+           (bprm->recursion_depth > BINPRM_MAX_RECURSION))
                return -ENOEXEC;
        /*
         * This section does the #! interpretation.
         * Sorta complicated, but hopefully it will work.  -TYT
         */
 
-       bprm->sh_bang = 1;
+       bprm->recursion_depth++;
        allow_write_access(bprm->file);
        fput(bprm->file);
        bprm->file = NULL;
index 68be580ba289fc3135a0dcd93595ce5b66062206..74e587a5279684f722b5b1733d1444ebf1ee1e35 100644 (file)
@@ -306,3 +306,5 @@ static void __exit exit_som_binfmt(void)
 
 core_initcall(init_som_binfmt);
 module_exit(exit_som_binfmt);
+
+MODULE_LICENSE("GPL");
index 3cb7cda3d780e95026142398f4c52cdf565d93b6..262fa10e213d571c4d14e1c6b08a3c5861e55e03 100644 (file)
@@ -22,9 +22,6 @@
 #include <linux/mutex.h>
 #include <linux/backing-dev.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
 #include "internal.h"
 
 /*
index 0d9b80ec689ccc0741fee358d92f26b34f1bc4c9..cfd29da714d1e9bf9b9f41338c09723ff09422de 100644 (file)
@@ -362,9 +362,8 @@ static int init_coda_psdev(void)
                goto out_chrdev;
        }               
        for (i = 0; i < MAX_CODADEVS; i++)
-               device_create_drvdata(coda_psdev_class, NULL,
-                                     MKDEV(CODA_PSDEV_MAJOR, i),
-                                     NULL, "cfs%d", i);
+               device_create(coda_psdev_class, NULL,
+                             MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i);
        coda_sysctl_init();
        goto out;
 
index 075d0509970de479c78e796cb4ce11d94945fbb5..5f9ec449c799854e19a9190b489ccf4a23fc0b03 100644 (file)
@@ -137,6 +137,45 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _
        return compat_sys_futimesat(AT_FDCWD, filename, t);
 }
 
+static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
+{
+       compat_ino_t ino = stat->ino;
+       typeof(ubuf->st_uid) uid = 0;
+       typeof(ubuf->st_gid) gid = 0;
+       int err;
+
+       SET_UID(uid, stat->uid);
+       SET_GID(gid, stat->gid);
+
+       if ((u64) stat->size > MAX_NON_LFS ||
+           !old_valid_dev(stat->dev) ||
+           !old_valid_dev(stat->rdev))
+               return -EOVERFLOW;
+       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+               return -EOVERFLOW;
+
+       if (clear_user(ubuf, sizeof(*ubuf)))
+               return -EFAULT;
+
+       err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
+       err |= __put_user(ino, &ubuf->st_ino);
+       err |= __put_user(stat->mode, &ubuf->st_mode);
+       err |= __put_user(stat->nlink, &ubuf->st_nlink);
+       err |= __put_user(uid, &ubuf->st_uid);
+       err |= __put_user(gid, &ubuf->st_gid);
+       err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
+       err |= __put_user(stat->size, &ubuf->st_size);
+       err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
+       err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
+       err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
+       err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
+       err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
+       err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
+       err |= __put_user(stat->blksize, &ubuf->st_blksize);
+       err |= __put_user(stat->blocks, &ubuf->st_blocks);
+       return err;
+}
+
 asmlinkage long compat_sys_newstat(char __user * filename,
                struct compat_stat __user *statbuf)
 {
@@ -1239,7 +1278,7 @@ static int compat_count(compat_uptr_t __user *argv, int max)
                        if (!p)
                                break;
                        argv++;
-                       if(++i > max)
+                       if (i++ >= max)
                                return -E2BIG;
                }
        }
index 9606ee848fd81c98ca9fc2cc496e0452140c9205..af0558dbe8b75a65bbe975f6dede7390ff0dbeb9 100644 (file)
@@ -5,11 +5,11 @@
  *
  * O_DIRECT
  *
- * 04Jul2002   akpm@zip.com.au
+ * 04Jul2002   Andrew Morton
  *             Initial version
  * 11Sep2002   janetinc@us.ibm.com
  *             added readv/writev support.
- * 29Oct2002   akpm@zip.com.au
+ * 29Oct2002   Andrew Morton
  *             rewrote bio_add_page() support.
  * 30Oct2002   pbadari@us.ibm.com
  *             added support for non-aligned IO.
index ad7e59003e0445943d21f8b9f78090f7b9e19b53..da30a27f2242c7e2e844b630ea02d12474ce7fdd 100644 (file)
@@ -9,8 +9,6 @@
  * implementation is based on one of the several variants of the LINUX
  * inode-subsystem with added complexity of the diskquota system.
  * 
- * Version: $Id: dquot.c,v 6.3 1996/11/17 18:35:34 mvw Exp mvw $
- * 
  * Author:     Marco van Wieringen <mvw@planets.elm.net>
  *
  * Fixes:   Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
index b4755a85996e9d6be9597fb92c05d668ff88713c..2cc9ee4ad2eb774f144e1d706276c7d037c6bb7d 100644 (file)
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
 
-ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o miscdev.o kthread.o debug.o
+ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o miscdev.o kthread.o debug.o
index b73fb752c5f8e9294ce232f4459efa26a79feed4..3504cf9df358076c840b2fe48f26000b965116e0 100644 (file)
 #define ECRYPTFS_MAX_PKI_NAME_BYTES 16
 #define ECRYPTFS_DEFAULT_NUM_USERS 4
 #define ECRYPTFS_MAX_NUM_USERS 32768
-#define ECRYPTFS_TRANSPORT_NETLINK 0
-#define ECRYPTFS_TRANSPORT_CONNECTOR 1
-#define ECRYPTFS_TRANSPORT_RELAYFS 2
-#define ECRYPTFS_TRANSPORT_MISCDEV 3
-#define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_MISCDEV
 #define ECRYPTFS_XATTR_NAME "user.ecryptfs"
 
 #define RFC2440_CIPHER_DES3_EDE 0x02
@@ -400,8 +395,6 @@ struct ecryptfs_msg_ctx {
        struct mutex mux;
 };
 
-extern unsigned int ecryptfs_transport;
-
 struct ecryptfs_daemon;
 
 struct ecryptfs_daemon {
@@ -627,31 +620,20 @@ int
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
                  size_t size, int flags);
 int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
-int ecryptfs_process_helo(unsigned int transport, uid_t euid,
-                         struct user_namespace *user_ns, struct pid *pid);
+int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns,
+                         struct pid *pid);
 int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns,
                          struct pid *pid);
 int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
                              struct user_namespace *user_ns, struct pid *pid,
                              u32 seq);
-int ecryptfs_send_message(unsigned int transport, char *data, int data_len,
+int ecryptfs_send_message(char *data, int data_len,
                          struct ecryptfs_msg_ctx **msg_ctx);
 int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
                               struct ecryptfs_message **emsg);
-int ecryptfs_init_messaging(unsigned int transport);
-void ecryptfs_release_messaging(unsigned int transport);
+int ecryptfs_init_messaging(void);
+void ecryptfs_release_messaging(void);
 
-int ecryptfs_send_netlink(char *data, int data_len,
-                         struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
-                         u16 msg_flags, struct pid *daemon_pid);
-int ecryptfs_init_netlink(void);
-void ecryptfs_release_netlink(void);
-
-int ecryptfs_send_connector(char *data, int data_len,
-                           struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
-                           u16 msg_flags, struct pid *daemon_pid);
-int ecryptfs_init_connector(void);
-void ecryptfs_release_connector(void);
 void
 ecryptfs_write_header_metadata(char *virt,
                               struct ecryptfs_crypt_stat *crypt_stat,
index 9244d653743ec02c6d279071095f76c08c834dd6..eb3dc4c7ac066c45c99d26218ccda7f623cae9c6 100644 (file)
@@ -71,12 +71,11 @@ struct ecryptfs_getdents_callback {
        void *dirent;
        struct dentry *dentry;
        filldir_t filldir;
-       int err;
        int filldir_called;
        int entries_written;
 };
 
-/* Inspired by generic filldir in fs/readir.c */
+/* Inspired by generic filldir in fs/readdir.c */
 static int
 ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset,
                 u64 ino, unsigned int d_type)
@@ -125,18 +124,18 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
        buf.dirent = dirent;
        buf.dentry = file->f_path.dentry;
        buf.filldir = filldir;
-retry:
        buf.filldir_called = 0;
        buf.entries_written = 0;
-       buf.err = 0;
        rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf);
-       if (buf.err)
-               rc = buf.err;
-       if (buf.filldir_called && !buf.entries_written)
-               goto retry;
        file->f_pos = lower_file->f_pos;
+       if (rc < 0)
+               goto out;
+       if (buf.filldir_called && !buf.entries_written)
+               goto out;
        if (rc >= 0)
-               fsstack_copy_attr_atime(inode, lower_file->f_path.dentry->d_inode);
+               fsstack_copy_attr_atime(inode,
+                                       lower_file->f_path.dentry->d_inode);
+out:
        return rc;
 }
 
index f5b76a331b9c743a3679ae69022f288c60b0f229..e22bc39613458e98fe35169b4de06412d9a4ec3f 100644 (file)
@@ -234,8 +234,8 @@ parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code,
        }
        i += data_len;
        if (message_len < (i + m_size)) {
-               ecryptfs_printk(KERN_ERR, "The received netlink message is "
-                               "shorter than expected\n");
+               ecryptfs_printk(KERN_ERR, "The message received from ecryptfsd "
+                               "is shorter than expected\n");
                rc = -EIO;
                goto out;
        }
@@ -438,8 +438,8 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
        struct ecryptfs_msg_ctx *msg_ctx;
        struct ecryptfs_message *msg = NULL;
        char *auth_tok_sig;
-       char *netlink_message;
-       size_t netlink_message_length;
+       char *payload;
+       size_t payload_len;
        int rc;
 
        rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
@@ -449,15 +449,15 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
                goto out;
        }
        rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key),
-                                &netlink_message, &netlink_message_length);
+                                &payload, &payload_len);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet\n");
                goto out;
        }
-       rc = ecryptfs_send_message(ecryptfs_transport, netlink_message,
-                                  netlink_message_length, &msg_ctx);
+       rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
        if (rc) {
-               ecryptfs_printk(KERN_ERR, "Error sending netlink message\n");
+               ecryptfs_printk(KERN_ERR, "Error sending message to "
+                               "ecryptfsd\n");
                goto out;
        }
        rc = ecryptfs_wait_for_response(msg_ctx, &msg);
@@ -1333,23 +1333,22 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
                        struct ecryptfs_key_record *key_rec)
 {
        struct ecryptfs_msg_ctx *msg_ctx = NULL;
-       char *netlink_payload;
-       size_t netlink_payload_length;
+       char *payload = NULL;
+       size_t payload_len;
        struct ecryptfs_message *msg;
        int rc;
 
        rc = write_tag_66_packet(auth_tok->token.private_key.signature,
                                 ecryptfs_code_for_cipher_string(crypt_stat),
-                                crypt_stat, &netlink_payload,
-                                &netlink_payload_length);
+                                crypt_stat, &payload, &payload_len);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n");
                goto out;
        }
-       rc = ecryptfs_send_message(ecryptfs_transport, netlink_payload,
-                                  netlink_payload_length, &msg_ctx);
+       rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
        if (rc) {
-               ecryptfs_printk(KERN_ERR, "Error sending netlink message\n");
+               ecryptfs_printk(KERN_ERR, "Error sending message to "
+                               "ecryptfsd\n");
                goto out;
        }
        rc = ecryptfs_wait_for_response(msg_ctx, &msg);
@@ -1364,8 +1363,7 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
                ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n");
        kfree(msg);
 out:
-       if (netlink_payload)
-               kfree(netlink_payload);
+       kfree(payload);
        return rc;
 }
 /**
index 8ebe9a5d1d993f1cacbcfa9ce62753f3f035b2e8..046e027a4cb192705a49caf27048ac79cf35badb 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/namei.h>
 #include <linux/skbuff.h>
 #include <linux/crypto.h>
-#include <linux/netlink.h>
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/key.h>
@@ -49,8 +48,7 @@ MODULE_PARM_DESC(ecryptfs_verbosity,
                 "0, which is Quiet)");
 
 /**
- * Module parameter that defines the number of netlink message buffer
- * elements
+ * Module parameter that defines the number of message buffer elements
  */
 unsigned int ecryptfs_message_buf_len = ECRYPTFS_DEFAULT_MSG_CTX_ELEMS;
 
@@ -60,9 +58,9 @@ MODULE_PARM_DESC(ecryptfs_message_buf_len,
 
 /**
  * Module parameter that defines the maximum guaranteed amount of time to wait
- * for a response through netlink.  The actual sleep time will be, more than
+ * for a response from ecryptfsd.  The actual sleep time will be, more than
  * likely, a small amount greater than this specified value, but only less if
- * the netlink message successfully arrives.
+ * the message successfully arrives.
  */
 signed long ecryptfs_message_wait_timeout = ECRYPTFS_MAX_MSG_CTX_TTL / HZ;
 
@@ -83,8 +81,6 @@ module_param(ecryptfs_number_of_users, uint, 0);
 MODULE_PARM_DESC(ecryptfs_number_of_users, "An estimate of the number of "
                 "concurrent users of eCryptfs");
 
-unsigned int ecryptfs_transport = ECRYPTFS_DEFAULT_TRANSPORT;
-
 void __ecryptfs_printk(const char *fmt, ...)
 {
        va_list args;
@@ -779,10 +775,11 @@ static int __init ecryptfs_init(void)
                       "rc = [%d]\n", __func__, rc);
                goto out_do_sysfs_unregistration;
        }
-       rc = ecryptfs_init_messaging(ecryptfs_transport);
+       rc = ecryptfs_init_messaging();
        if (rc) {
                printk(KERN_ERR "Failure occured while attempting to "
-                               "initialize the eCryptfs netlink socket\n");
+                               "initialize the communications channel to "
+                               "ecryptfsd\n");
                goto out_destroy_kthread;
        }
        rc = ecryptfs_init_crypto();
@@ -797,7 +794,7 @@ static int __init ecryptfs_init(void)
 
        goto out;
 out_release_messaging:
-       ecryptfs_release_messaging(ecryptfs_transport);
+       ecryptfs_release_messaging();
 out_destroy_kthread:
        ecryptfs_destroy_kthread();
 out_do_sysfs_unregistration:
@@ -818,7 +815,7 @@ static void __exit ecryptfs_exit(void)
        if (rc)
                printk(KERN_ERR "Failure whilst attempting to destroy crypto; "
                       "rc = [%d]\n", rc);
-       ecryptfs_release_messaging(ecryptfs_transport);
+       ecryptfs_release_messaging();
        ecryptfs_destroy_kthread();
        do_sysfs_unregistration();
        unregister_filesystem(&ecryptfs_fs_type);
index 1b5c20058acbeefddc1031f5700993da2e799c58..c6983978a31eda7218fa921b954848e2d4a5c42c 100644 (file)
@@ -134,12 +134,11 @@ out:
 }
 
 static int
-ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
-                            u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx);
+ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
+                            struct ecryptfs_msg_ctx **msg_ctx);
 
 /**
  * ecryptfs_send_raw_message
- * @transport: Transport type
  * @msg_type: Message type
  * @daemon: Daemon struct for recipient of message
  *
@@ -150,38 +149,25 @@ ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
  *
  * Returns zero on success; non-zero otherwise
  */
-static int ecryptfs_send_raw_message(unsigned int transport, u8 msg_type,
+static int ecryptfs_send_raw_message(u8 msg_type,
                                     struct ecryptfs_daemon *daemon)
 {
        struct ecryptfs_msg_ctx *msg_ctx;
        int rc;
 
-       switch(transport) {
-       case ECRYPTFS_TRANSPORT_NETLINK:
-               rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0,
-                                          daemon->pid);
-               break;
-       case ECRYPTFS_TRANSPORT_MISCDEV:
-               rc = ecryptfs_send_message_locked(transport, NULL, 0, msg_type,
-                                                 &msg_ctx);
-               if (rc) {
-                       printk(KERN_ERR "%s: Error whilst attempting to send "
-                              "message via procfs; rc = [%d]\n", __func__, rc);
-                       goto out;
-               }
-               /* Raw messages are logically context-free (e.g., no
-                * reply is expected), so we set the state of the
-                * ecryptfs_msg_ctx object to indicate that it should
-                * be freed as soon as the transport sends out the message. */
-               mutex_lock(&msg_ctx->mux);
-               msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY;
-               mutex_unlock(&msg_ctx->mux);
-               break;
-       case ECRYPTFS_TRANSPORT_CONNECTOR:
-       case ECRYPTFS_TRANSPORT_RELAYFS:
-       default:
-               rc = -ENOSYS;
+       rc = ecryptfs_send_message_locked(NULL, 0, msg_type, &msg_ctx);
+       if (rc) {
+               printk(KERN_ERR "%s: Error whilst attempting to send "
+                      "message to ecryptfsd; rc = [%d]\n", __func__, rc);
+               goto out;
        }
+       /* Raw messages are logically context-free (e.g., no
+        * reply is expected), so we set the state of the
+        * ecryptfs_msg_ctx object to indicate that it should
+        * be freed as soon as the message is sent. */
+       mutex_lock(&msg_ctx->mux);
+       msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY;
+       mutex_unlock(&msg_ctx->mux);
 out:
        return rc;
 }
@@ -227,7 +213,6 @@ out:
 
 /**
  * ecryptfs_process_helo
- * @transport: The underlying transport (netlink, etc.)
  * @euid: The user ID owner of the message
  * @user_ns: The namespace in which @euid applies
  * @pid: The process ID for the userspace program that sent the
@@ -239,8 +224,8 @@ out:
  * Returns zero after adding a new daemon to the hash list;
  * non-zero otherwise.
  */
-int ecryptfs_process_helo(unsigned int transport, uid_t euid,
-                         struct user_namespace *user_ns, struct pid *pid)
+int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns,
+                         struct pid *pid)
 {
        struct ecryptfs_daemon *new_daemon;
        struct ecryptfs_daemon *old_daemon;
@@ -252,8 +237,7 @@ int ecryptfs_process_helo(unsigned int transport, uid_t euid,
                printk(KERN_WARNING "Received request from user [%d] "
                       "to register daemon [0x%p]; unregistering daemon "
                       "[0x%p]\n", euid, pid, old_daemon->pid);
-               rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT,
-                                              old_daemon);
+               rc = ecryptfs_send_raw_message(ECRYPTFS_MSG_QUIT, old_daemon);
                if (rc)
                        printk(KERN_WARNING "Failed to send QUIT "
                               "message to daemon [0x%p]; rc = [%d]\n",
@@ -467,8 +451,6 @@ out:
 
 /**
  * ecryptfs_send_message_locked
- * @transport: The transport over which to send the message (i.e.,
- *             netlink)
  * @data: The data to send
  * @data_len: The length of data
  * @msg_ctx: The message context allocated for the send
@@ -478,8 +460,8 @@ out:
  * Returns zero on success; non-zero otherwise
  */
 static int
-ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
-                            u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx)
+ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
+                            struct ecryptfs_msg_ctx **msg_ctx)
 {
        struct ecryptfs_daemon *daemon;
        int rc;
@@ -503,20 +485,8 @@ ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
        ecryptfs_msg_ctx_free_to_alloc(*msg_ctx);
        mutex_unlock(&(*msg_ctx)->mux);
        mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
-       switch (transport) {
-       case ECRYPTFS_TRANSPORT_NETLINK:
-               rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, msg_type,
-                                          0, daemon->pid);
-               break;
-       case ECRYPTFS_TRANSPORT_MISCDEV:
-               rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type,
-                                          0, daemon);
-               break;
-       case ECRYPTFS_TRANSPORT_CONNECTOR:
-       case ECRYPTFS_TRANSPORT_RELAYFS:
-       default:
-               rc = -ENOSYS;
-       }
+       rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type, 0,
+                                  daemon);
        if (rc)
                printk(KERN_ERR "%s: Error attempting to send message to "
                       "userspace daemon; rc = [%d]\n", __func__, rc);
@@ -526,8 +496,6 @@ out:
 
 /**
  * ecryptfs_send_message
- * @transport: The transport over which to send the message (i.e.,
- *             netlink)
  * @data: The data to send
  * @data_len: The length of data
  * @msg_ctx: The message context allocated for the send
@@ -536,14 +504,14 @@ out:
  *
  * Returns zero on success; non-zero otherwise
  */
-int ecryptfs_send_message(unsigned int transport, char *data, int data_len,
+int ecryptfs_send_message(char *data, int data_len,
                          struct ecryptfs_msg_ctx **msg_ctx)
 {
        int rc;
 
        mutex_lock(&ecryptfs_daemon_hash_mux);
-       rc = ecryptfs_send_message_locked(transport, data, data_len,
-                                         ECRYPTFS_MSG_REQUEST, msg_ctx);
+       rc = ecryptfs_send_message_locked(data, data_len, ECRYPTFS_MSG_REQUEST,
+                                         msg_ctx);
        mutex_unlock(&ecryptfs_daemon_hash_mux);
        return rc;
 }
@@ -586,7 +554,7 @@ sleep:
        return rc;
 }
 
-int ecryptfs_init_messaging(unsigned int transport)
+int ecryptfs_init_messaging(void)
 {
        int i;
        int rc = 0;
@@ -639,27 +607,14 @@ int ecryptfs_init_messaging(unsigned int transport)
                mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux);
        }
        mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
-       switch(transport) {
-       case ECRYPTFS_TRANSPORT_NETLINK:
-               rc = ecryptfs_init_netlink();
-               if (rc)
-                       ecryptfs_release_messaging(transport);
-               break;
-       case ECRYPTFS_TRANSPORT_MISCDEV:
-               rc = ecryptfs_init_ecryptfs_miscdev();
-               if (rc)
-                       ecryptfs_release_messaging(transport);
-               break;
-       case ECRYPTFS_TRANSPORT_CONNECTOR:
-       case ECRYPTFS_TRANSPORT_RELAYFS:
-       default:
-               rc = -ENOSYS;
-       }
+       rc = ecryptfs_init_ecryptfs_miscdev();
+       if (rc)
+               ecryptfs_release_messaging();
 out:
        return rc;
 }
 
-void ecryptfs_release_messaging(unsigned int transport)
+void ecryptfs_release_messaging(void)
 {
        if (ecryptfs_msg_ctx_arr) {
                int i;
@@ -698,17 +653,6 @@ void ecryptfs_release_messaging(unsigned int transport)
                kfree(ecryptfs_daemon_hash);
                mutex_unlock(&ecryptfs_daemon_hash_mux);
        }
-       switch(transport) {
-       case ECRYPTFS_TRANSPORT_NETLINK:
-               ecryptfs_release_netlink();
-               break;
-       case ECRYPTFS_TRANSPORT_MISCDEV:
-               ecryptfs_destroy_ecryptfs_miscdev();
-               break;
-       case ECRYPTFS_TRANSPORT_CONNECTOR:
-       case ECRYPTFS_TRANSPORT_RELAYFS:
-       default:
-               break;
-       }
+       ecryptfs_destroy_ecryptfs_miscdev();
        return;
 }
index 245c2dc02d5cfa96d1fe60818ae849555ef5e991..04d7b3fa1ac6cd7679237cd2188a385c67bf960c 100644 (file)
@@ -265,22 +265,34 @@ out:
 }
 
 /**
- * ecryptfs_prepare_write
+ * ecryptfs_write_begin
  * @file: The eCryptfs file
- * @page: The eCryptfs page
- * @from: The start byte from which we will write
- * @to: The end byte to which we will write
+ * @mapping: The eCryptfs object
+ * @pos: The file offset at which to start writing
+ * @len: Length of the write
+ * @flags: Various flags
+ * @pagep: Pointer to return the page
+ * @fsdata: Pointer to return fs data (unused)
  *
  * This function must zero any hole we create
  *
  * Returns zero on success; non-zero otherwise
  */
-static int ecryptfs_prepare_write(struct file *file, struct page *page,
-                                 unsigned from, unsigned to)
+static int ecryptfs_write_begin(struct file *file,
+                       struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata)
 {
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+       struct page *page;
        loff_t prev_page_end_size;
        int rc = 0;
 
+       page = __grab_cache_page(mapping, index);
+       if (!page)
+               return -ENOMEM;
+       *pagep = page;
+
        if (!PageUptodate(page)) {
                struct ecryptfs_crypt_stat *crypt_stat =
                        &ecryptfs_inode_to_private(
@@ -289,8 +301,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
                if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
                    || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
                        rc = ecryptfs_read_lower_page_segment(
-                               page, page->index, 0, PAGE_CACHE_SIZE,
-                               page->mapping->host);
+                               page, index, 0, PAGE_CACHE_SIZE, mapping->host);
                        if (rc) {
                                printk(KERN_ERR "%s: Error attemping to read "
                                       "lower page segment; rc = [%d]\n",
@@ -316,8 +327,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
                                SetPageUptodate(page);
                        } else {
                                rc = ecryptfs_read_lower_page_segment(
-                                       page, page->index, 0, PAGE_CACHE_SIZE,
-                                       page->mapping->host);
+                                       page, index, 0, PAGE_CACHE_SIZE,
+                                       mapping->host);
                                if (rc) {
                                        printk(KERN_ERR "%s: Error reading "
                                               "page; rc = [%d]\n",
@@ -339,10 +350,10 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
                        SetPageUptodate(page);
                }
        }
-       prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
+       prev_page_end_size = ((loff_t)index << PAGE_CACHE_SHIFT);
        /* If creating a page or more of holes, zero them out via truncate.
         * Note, this will increase i_size. */
-       if (page->index != 0) {
+       if (index != 0) {
                if (prev_page_end_size > i_size_read(page->mapping->host)) {
                        rc = ecryptfs_truncate(file->f_path.dentry,
                                               prev_page_end_size);
@@ -357,8 +368,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
        }
        /* Writing to a new page, and creating a small hole from start
         * of page?  Zero it out. */
-       if ((i_size_read(page->mapping->host) == prev_page_end_size)
-           && (from != 0))
+       if ((i_size_read(mapping->host) == prev_page_end_size)
+           && (pos != 0))
                zero_user(page, 0, PAGE_CACHE_SIZE);
 out:
        return rc;
@@ -445,21 +456,28 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
 }
 
 /**
- * ecryptfs_commit_write
+ * ecryptfs_write_end
  * @file: The eCryptfs file object
+ * @mapping: The eCryptfs object
+ * @pos: The file position
+ * @len: The length of the data (unused)
+ * @copied: The amount of data copied
  * @page: The eCryptfs page
- * @from: Ignored (we rotate the page IV on each write)
- * @to: Ignored
+ * @fsdata: The fsdata (unused)
  *
  * This is where we encrypt the data and pass the encrypted data to
  * the lower filesystem.  In OpenPGP-compatible mode, we operate on
  * entire underlying packets.
  */
-static int ecryptfs_commit_write(struct file *file, struct page *page,
-                                unsigned from, unsigned to)
+static int ecryptfs_write_end(struct file *file,
+                       struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+                       struct page *page, void *fsdata)
 {
-       loff_t pos;
-       struct inode *ecryptfs_inode = page->mapping->host;
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+       unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+       unsigned to = from + copied;
+       struct inode *ecryptfs_inode = mapping->host;
        struct ecryptfs_crypt_stat *crypt_stat =
                &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
        int rc;
@@ -471,25 +489,22 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
        } else
                ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
        ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
-                       "(page w/ index = [0x%.16x], to = [%d])\n", page->index,
-                       to);
+                       "(page w/ index = [0x%.16x], to = [%d])\n", index, to);
        /* Fills in zeros if 'to' goes beyond inode size */
        rc = fill_zeros_to_end_of_page(page, to);
        if (rc) {
                ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
-                               "zeros in page with index = [0x%.16x]\n",
-                               page->index);
+                       "zeros in page with index = [0x%.16x]\n", index);
                goto out;
        }
        rc = ecryptfs_encrypt_page(page);
        if (rc) {
                ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
-                               "index [0x%.16x])\n", page->index);
+                               "index [0x%.16x])\n", index);
                goto out;
        }
-       pos = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + to;
-       if (pos > i_size_read(ecryptfs_inode)) {
-               i_size_write(ecryptfs_inode, pos);
+       if (pos + copied > i_size_read(ecryptfs_inode)) {
+               i_size_write(ecryptfs_inode, pos + copied);
                ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
                                "[0x%.16x]\n", i_size_read(ecryptfs_inode));
        }
@@ -497,7 +512,11 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
        if (rc)
                printk(KERN_ERR "Error writing inode size to metadata; "
                       "rc = [%d]\n", rc);
+       else
+               rc = copied;
 out:
+       unlock_page(page);
+       page_cache_release(page);
        return rc;
 }
 
@@ -518,7 +537,7 @@ static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
 struct address_space_operations ecryptfs_aops = {
        .writepage = ecryptfs_writepage,
        .readpage = ecryptfs_readpage,
-       .prepare_write = ecryptfs_prepare_write,
-       .commit_write = ecryptfs_commit_write,
+       .write_begin = ecryptfs_write_begin,
+       .write_end = ecryptfs_write_end,
        .bmap = ecryptfs_bmap,
 };
diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c
deleted file mode 100644 (file)
index e0abad6..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * eCryptfs: Linux filesystem encryption layer
- *
- * Copyright (C) 2004-2006 International Business Machines Corp.
- *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
- *             Tyler Hicks <tyhicks@ou.edu>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <net/sock.h>
-#include <linux/hash.h>
-#include <linux/random.h>
-#include "ecryptfs_kernel.h"
-
-static struct sock *ecryptfs_nl_sock;
-
-/**
- * ecryptfs_send_netlink
- * @data: The data to include as the payload
- * @data_len: The byte count of the data
- * @msg_ctx: The netlink context that will be used to handle the
- *          response message
- * @msg_type: The type of netlink message to send
- * @msg_flags: The flags to include in the netlink header
- * @daemon_pid: The process id of the daemon to send the message to
- *
- * Sends the data to the specified daemon pid and uses the netlink
- * context element to store the data needed for validation upon
- * receiving the response.  The data and the netlink context can be
- * null if just sending a netlink header is sufficient.  Returns zero
- * upon sending the message; non-zero upon error.
- */
-int ecryptfs_send_netlink(char *data, int data_len,
-                         struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
-                         u16 msg_flags, struct pid *daemon_pid)
-{
-       struct sk_buff *skb;
-       struct nlmsghdr *nlh;
-       struct ecryptfs_message *msg;
-       size_t payload_len;
-       int rc;
-
-       payload_len = ((data && data_len) ? (sizeof(*msg) + data_len) : 0);
-       skb = alloc_skb(NLMSG_SPACE(payload_len), GFP_KERNEL);
-       if (!skb) {
-               rc = -ENOMEM;
-               ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n");
-               goto out;
-       }
-       nlh = NLMSG_PUT(skb, pid_nr(daemon_pid), msg_ctx ? msg_ctx->counter : 0,
-                       msg_type, payload_len);
-       nlh->nlmsg_flags = msg_flags;
-       if (msg_ctx && payload_len) {
-               msg = (struct ecryptfs_message *)NLMSG_DATA(nlh);
-               msg->index = msg_ctx->index;
-               msg->data_len = data_len;
-               memcpy(msg->data, data, data_len);
-       }
-       rc = netlink_unicast(ecryptfs_nl_sock, skb, pid_nr(daemon_pid), 0);
-       if (rc < 0) {
-               ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink "
-                               "message; rc = [%d]\n", rc);
-               goto out;
-       }
-       rc = 0;
-       goto out;
-nlmsg_failure:
-       rc = -EMSGSIZE;
-       kfree_skb(skb);
-out:
-       return rc;
-}
-
-/**
- * ecryptfs_process_nl_reponse
- * @skb: The socket buffer containing the netlink message of state
- *       RESPONSE
- *
- * Processes a response message after sending a operation request to
- * userspace.  Attempts to assign the msg to a netlink context element
- * at the index specified in the msg.  The sk_buff and nlmsghdr must
- * be validated before this function. Returns zero upon delivery to
- * desired context element; non-zero upon delivery failure or error.
- */
-static int ecryptfs_process_nl_response(struct sk_buff *skb)
-{
-       struct nlmsghdr *nlh = nlmsg_hdr(skb);
-       struct ecryptfs_message *msg = NLMSG_DATA(nlh);
-       struct pid *pid;
-       int rc;
-
-       if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) {
-               rc = -EINVAL;
-               ecryptfs_printk(KERN_ERR, "Received netlink message with "
-                               "incorrectly specified data length\n");
-               goto out;
-       }
-       pid = find_get_pid(NETLINK_CREDS(skb)->pid);
-       rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, NULL,
-                                      pid, nlh->nlmsg_seq);
-       put_pid(pid);
-       if (rc)
-               printk(KERN_ERR
-                      "Error processing response message; rc = [%d]\n", rc);
-out:
-       return rc;
-}
-
-/**
- * ecryptfs_process_nl_helo
- * @skb: The socket buffer containing the nlmsghdr in HELO state
- *
- * Gets uid and pid of the skb and adds the values to the daemon id
- * hash. Returns zero after adding a new daemon id to the hash list;
- * non-zero otherwise.
- */
-static int ecryptfs_process_nl_helo(struct sk_buff *skb)
-{
-       struct pid *pid;
-       int rc;
-
-       pid = find_get_pid(NETLINK_CREDS(skb)->pid);
-       rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK,
-                                  NETLINK_CREDS(skb)->uid, NULL, pid);
-       put_pid(pid);
-       if (rc)
-               printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc);
-       return rc;
-}
-
-/**
- * ecryptfs_process_nl_quit
- * @skb: The socket buffer containing the nlmsghdr in QUIT state
- *
- * Gets uid and pid of the skb and deletes the corresponding daemon
- * id, if it is the registered that is requesting the
- * deletion. Returns zero after deleting the desired daemon id;
- * non-zero otherwise.
- */
-static int ecryptfs_process_nl_quit(struct sk_buff *skb)
-{
-       struct pid *pid;
-       int rc;
-
-       pid = find_get_pid(NETLINK_CREDS(skb)->pid);
-       rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, NULL, pid);
-       put_pid(pid);
-       if (rc)
-               printk(KERN_WARNING
-                      "Error processing QUIT message; rc = [%d]\n", rc);
-       return rc;
-}
-
-/**
- * ecryptfs_receive_nl_message
- *
- * Callback function called by netlink system when a message arrives.
- * If the message looks to be valid, then an attempt is made to assign
- * it to its desired netlink context element and wake up the process
- * that is waiting for a response.
- */
-static void ecryptfs_receive_nl_message(struct sk_buff *skb)
-{
-       struct nlmsghdr *nlh;
-
-       nlh = nlmsg_hdr(skb);
-       if (!NLMSG_OK(nlh, skb->len)) {
-               ecryptfs_printk(KERN_ERR, "Received corrupt netlink "
-                               "message\n");
-               goto free;
-       }
-       switch (nlh->nlmsg_type) {
-               case ECRYPTFS_MSG_RESPONSE:
-                       if (ecryptfs_process_nl_response(skb)) {
-                               ecryptfs_printk(KERN_WARNING, "Failed to "
-                                               "deliver netlink response to "
-                                               "requesting operation\n");
-                       }
-                       break;
-               case ECRYPTFS_MSG_HELO:
-                       if (ecryptfs_process_nl_helo(skb)) {
-                               ecryptfs_printk(KERN_WARNING, "Failed to "
-                                               "fulfill HELO request\n");
-                       }
-                       break;
-               case ECRYPTFS_MSG_QUIT:
-                       if (ecryptfs_process_nl_quit(skb)) {
-                               ecryptfs_printk(KERN_WARNING, "Failed to "
-                                               "fulfill QUIT request\n");
-                       }
-                       break;
-               default:
-                       ecryptfs_printk(KERN_WARNING, "Dropping netlink "
-                                       "message of unrecognized type [%d]\n",
-                                       nlh->nlmsg_type);
-                       break;
-       }
-free:
-       kfree_skb(skb);
-}
-
-/**
- * ecryptfs_init_netlink
- *
- * Initializes the daemon id hash list, netlink context array, and
- * necessary locks.  Returns zero upon success; non-zero upon error.
- */
-int ecryptfs_init_netlink(void)
-{
-       int rc;
-
-       ecryptfs_nl_sock = netlink_kernel_create(&init_net, NETLINK_ECRYPTFS, 0,
-                                                ecryptfs_receive_nl_message,
-                                                NULL, THIS_MODULE);
-       if (!ecryptfs_nl_sock) {
-               rc = -EIO;
-               ecryptfs_printk(KERN_ERR, "Failed to create netlink socket\n");
-               goto out;
-       }
-       ecryptfs_nl_sock->sk_sndtimeo = ECRYPTFS_DEFAULT_SEND_TIMEOUT;
-       rc = 0;
-out:
-       return rc;
-}
-
-/**
- * ecryptfs_release_netlink
- *
- * Frees all memory used by the netlink context array and releases the
- * netlink socket.
- */
-void ecryptfs_release_netlink(void)
-{
-       netlink_kernel_release(ecryptfs_nl_sock);
-       ecryptfs_nl_sock = NULL;
-}
index 7cc0eb756b55e99e5f876eaa43c6c4e466b27b05..99368bda0261321290a6afa52ad74a797f79cd54 100644 (file)
@@ -927,14 +927,11 @@ errxit:
        /*
         * During the time we spent in the loop above, some other events
         * might have been queued by the poll callback. We re-insert them
-        * here (in case they are not already queued, or they're one-shot).
+        * inside the main ready-list here.
         */
        for (nepi = ep->ovflist; (epi = nepi) != NULL;
-            nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
-               if (!ep_is_linked(&epi->rdllink) &&
-                   (epi->event.events & ~EP_PRIVATE_BITS))
-                       list_add_tail(&epi->rdllink, &ep->rdllist);
-       }
+            nepi = epi->next, epi->next = EP_UNACTIVE_PTR)
+               list_add_tail(&epi->rdllink, &ep->rdllist);
        /*
         * We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
         * releasing the lock, events will be queued in the normal way inside
index cecee501ce78805c32c9d007c658fce1e87b0a97..a41e7902ed0bf9ef9e2cd600c31b1acda0576ed4 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
 #include <linux/cn_proc.h>
 #include <linux/audit.h>
 #include <linux/tracehook.h>
+#include <linux/kmod.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
 
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
 #ifdef __alpha__
 /* for /sbin/loader handling in search_binary_handler() */
 #include <linux/a.out.h>
@@ -391,7 +388,7 @@ static int count(char __user * __user * argv, int max)
                        if (!p)
                                break;
                        argv++;
-                       if(++i > max)
+                       if (i++ >= max)
                                return -E2BIG;
                        cond_resched();
                }
@@ -825,8 +822,6 @@ static int de_thread(struct task_struct *tsk)
                        schedule();
                }
 
-               if (unlikely(task_child_reaper(tsk) == leader))
-                       task_active_pid_ns(tsk)->child_reaper = tsk;
                /*
                 * The only record we have of the real-time age of a
                 * process, regardless of execs it's done, is start_time.
@@ -1189,7 +1184,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                        return retval;
 
                /* Remember if the application is TASO.  */
-               bprm->sh_bang = eh->ah.entry < 0x100000000UL;
+               bprm->taso = eh->ah.entry < 0x100000000UL;
 
                bprm->file = file;
                bprm->loader = loader;
@@ -1247,8 +1242,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                read_unlock(&binfmt_lock);
                if (retval != -ENOEXEC || bprm->mm == NULL) {
                        break;
-#ifdef CONFIG_KMOD
-               }else{
+#ifdef CONFIG_MODULES
+               } else {
 #define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
                        if (printable(bprm->buf[0]) &&
                            printable(bprm->buf[1]) &&
index 10bb02c3f25cfcdee98897b6d7efe96e5f3ae6a1..6dac7ba2d22d7ff41855b7866f757417612c09ea 100644 (file)
@@ -1295,6 +1295,7 @@ retry_alloc:
         * turn off reservation for this allocation
         */
        if (my_rsv && (free_blocks < windowsz)
+               && (free_blocks > 0)
                && (rsv_is_empty(&my_rsv->rsv_window)))
                my_rsv = NULL;
 
@@ -1332,7 +1333,7 @@ retry_alloc:
                 * free blocks is less than half of the reservation
                 * window size.
                 */
-               if (free_blocks <= (windowsz/2))
+               if (my_rsv && (free_blocks <= (windowsz/2)))
                        continue;
 
                brelse(bitmap_bh);
index a78c6b4af06012a82c6a1ed3095b9ce4fc2e22fb..11a49ce84392a1e39bc1c335273c4f1ab2ee0d8f 100644 (file)
@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
        return err;
 }
 
-static void ext2_check_page(struct page *page)
+static void ext2_check_page(struct page *page, int quiet)
 {
        struct inode *dir = page->mapping->host;
        struct super_block *sb = dir->i_sb;
@@ -146,10 +146,10 @@ out:
        /* Too bad, we had an error */
 
 Ebadsize:
-       ext2_error(sb, "ext2_check_page",
-               "size of directory #%lu is not a multiple of chunk size",
-               dir->i_ino
-       );
+       if (!quiet)
+               ext2_error(sb, __func__,
+                       "size of directory #%lu is not a multiple "
+                       "of chunk size", dir->i_ino);
        goto fail;
 Eshort:
        error = "rec_len is smaller than minimal";
@@ -166,32 +166,36 @@ Espan:
 Einumber:
        error = "inode out of bounds";
 bad_entry:
-       ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
-               "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
-               dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
-               (unsigned long) le32_to_cpu(p->inode),
-               rec_len, p->name_len);
+       if (!quiet)
+               ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
+                       "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+                       dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+                       (unsigned long) le32_to_cpu(p->inode),
+                       rec_len, p->name_len);
        goto fail;
 Eend:
-       p = (ext2_dirent *)(kaddr + offs);
-       ext2_error (sb, "ext2_check_page",
-               "entry in directory #%lu spans the page boundary"
-               "offset=%lu, inode=%lu",
-               dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
-               (unsigned long) le32_to_cpu(p->inode));
+       if (!quiet) {
+               p = (ext2_dirent *)(kaddr + offs);
+               ext2_error(sb, "ext2_check_page",
+                       "entry in directory #%lu spans the page boundary"
+                       "offset=%lu, inode=%lu",
+                       dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+                       (unsigned long) le32_to_cpu(p->inode));
+       }
 fail:
        SetPageChecked(page);
        SetPageError(page);
 }
 
-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
+static struct page * ext2_get_page(struct inode *dir, unsigned long n,
+                                  int quiet)
 {
        struct address_space *mapping = dir->i_mapping;
        struct page *page = read_mapping_page(mapping, n, NULL);
        if (!IS_ERR(page)) {
                kmap(page);
                if (!PageChecked(page))
-                       ext2_check_page(page);
+                       ext2_check_page(page, quiet);
                if (PageError(page))
                        goto fail;
        }
@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
        for ( ; n < npages; n++, offset = 0) {
                char *kaddr, *limit;
                ext2_dirent *de;
-               struct page *page = ext2_get_page(inode, n);
+               struct page *page = ext2_get_page(inode, n, 0);
 
                if (IS_ERR(page)) {
                        ext2_error(sb, __func__,
@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
        struct page *page = NULL;
        struct ext2_inode_info *ei = EXT2_I(dir);
        ext2_dirent * de;
+       int dir_has_error = 0;
 
        if (npages == 0)
                goto out;
@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
        n = start;
        do {
                char *kaddr;
-               page = ext2_get_page(dir, n);
+               page = ext2_get_page(dir, n, dir_has_error);
                if (!IS_ERR(page)) {
                        kaddr = page_address(page);
                        de = (ext2_dirent *) kaddr;
@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
                                de = ext2_next_entry(de);
                        }
                        ext2_put_page(page);
-               }
+               } else
+                       dir_has_error = 1;
+
                if (++n >= npages)
                        n = 0;
                /* next page is past the blocks we've got */
@@ -414,7 +421,7 @@ found:
 
 struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
 {
-       struct page *page = ext2_get_page(dir, 0);
+       struct page *page = ext2_get_page(dir, 0, 0);
        ext2_dirent *de = NULL;
 
        if (!IS_ERR(page)) {
@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
        for (n = 0; n <= npages; n++) {
                char *dir_end;
 
-               page = ext2_get_page(dir, n);
+               page = ext2_get_page(dir, n, 0);
                err = PTR_ERR(page);
                if (IS_ERR(page))
                        goto out;
@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode)
 {
        struct page *page = NULL;
        unsigned long i, npages = dir_pages(inode);
+       int dir_has_error = 0;
 
        for (i = 0; i < npages; i++) {
                char *kaddr;
                ext2_dirent * de;
-               page = ext2_get_page(inode, i);
+               page = ext2_get_page(inode, i, dir_has_error);
 
-               if (IS_ERR(page))
+               if (IS_ERR(page)) {
+                       dir_has_error = 1;
                        continue;
+               }
 
                kaddr = page_address(page);
                de = (ext2_dirent *)kaddr;
index 25adfc3c693ab4673777801ecc0e014db9624ec8..d0ff0b8cf30988a23ad144f92f8b7543790bbe67 100644 (file)
@@ -8,7 +8,7 @@
  * pages against inodes.  ie: data writeback.  Writeout of the
  * inode itself is not handled here.
  *
- * 10Apr2002   akpm@zip.com.au
+ * 10Apr2002   Andrew Morton
  *             Split out of fs/inode.c
  *             Additions for address_space-based writeback
  */
index ba851576ebb13233eb2c84b4dc968f2caa2218f6..6d98f116ca03d610a1477dc77558c899f5abe48d 100644 (file)
@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
 
        fd->search_key->cat.ParID = rec.thread.ParID;
        len = fd->search_key->cat.CName.len = rec.thread.CName.len;
+       if (len > HFS_NAMELEN) {
+               printk(KERN_ERR "hfs: bad catalog namelength\n");
+               return -EIO;
+       }
        memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
        return hfs_brec_find(fd);
 }
index d128a25b74d2e78ae14b5e06473629add09d620b..ea30afc2a03c774221cc17341c446d30a0cb341b 100644 (file)
@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
        mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
        mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
        page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
+       if (IS_ERR(page)) {
+               start = size;
+               goto out;
+       }
        pptr = kmap(page);
        curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
        i = offset % 32;
@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
                        break;
                page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
                                         NULL);
+               if (IS_ERR(page)) {
+                       start = size;
+                       goto out;
+               }
                curr = pptr = kmap(page);
                if ((size ^ offset) / PAGE_CACHE_BITS)
                        end = pptr + PAGE_CACHE_BITS / 32;
@@ -120,6 +128,10 @@ found:
                offset += PAGE_CACHE_BITS;
                page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
                                         NULL);
+               if (IS_ERR(page)) {
+                       start = size;
+                       goto out;
+               }
                pptr = kmap(page);
                curr = pptr;
                end = pptr + PAGE_CACHE_BITS / 32;
index ba117c445e78d8127e9835fd37a1bd50c07791f0..f6874acb2cf2a3a81a242f1983600eb912b9f607 100644 (file)
@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
                return -EIO;
        }
 
+       if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
+               printk(KERN_ERR "hfs: catalog name length corrupted\n");
+               return -EIO;
+       }
+
        hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
                                 &tmp.thread.nodeName);
        return hfs_brec_find(fd);
index e834e578c93f8f475f0194831a214e8eb4534138..eb74531a0a8e267bec8491a18a83ed65b1a8d853 100644 (file)
@@ -356,7 +356,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
        } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
                printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n");
                sb->s_flags |= MS_RDONLY;
-       } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
+       } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && !(sb->s_flags & MS_RDONLY)) {
                printk(KERN_WARNING "hfs: write access to a journaled filesystem is not supported, "
                       "use the force option at your own risk, mounting read-only.\n");
                sb->s_flags |= MS_RDONLY;
index dbcc7af76a15d483a5efc5c1a68aa11566072623..552b80b3facc01414967771ec6d59d9029276cdb 100644 (file)
@@ -6,7 +6,7 @@
  * Contains functions related to preparing and submitting BIOs which contain
  * multiple pagecache pages.
  *
- * 15May2002   akpm@zip.com.au
+ * 15May2002   Andrew Morton
  *             Initial version
  * 27Jun2002   axboe@suse.de
  *             use bio_add_page() to build bio's just the right size
index 64965e1c21c46ca2dcb9aae20611a0725e9d4f4b..9b0efdad89100bd60e5a15954b67ca83495cad56 100644 (file)
@@ -13,9 +13,7 @@
 #include <linux/nls.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#ifdef CONFIG_KMOD
 #include <linux/kmod.h>
-#endif
 #include <linux/spinlock.h>
 
 static struct nls_table default_table;
@@ -215,24 +213,7 @@ static struct nls_table *find_nls(char *charset)
 
 struct nls_table *load_nls(char *charset)
 {
-       struct nls_table *nls;
-#ifdef CONFIG_KMOD
-       int ret;
-#endif
-
-       nls = find_nls(charset);
-       if (nls)
-               return nls;
-
-#ifdef CONFIG_KMOD
-       ret = request_module("nls_%s", charset);
-       if (ret != 0) {
-               printk("Unable to load NLS charset %s\n", charset);
-               return NULL;
-       }
-       nls = find_nls(charset);
-#endif
-       return nls;
+       return try_then_request_module(find_nls(charset), "nls_%s", charset);
 }
 
 void unload_nls(struct nls_table *nls)
index c25780a70dfd6757864c68ed685df1537a6a2937..802c41492214ca928cd30448deb972bbbbe6a05f 100644 (file)
@@ -2349,7 +2349,7 @@ static int ocfs2_xattr_bucket_find(struct inode *inode,
                 */
                ret = ocfs2_read_blocks(inode, xs->bucket.bhs[0]->b_blocknr + 1,
                                        blk_per_bucket - 1, &xs->bucket.bhs[1],
-                                       OCFS2_BH_CACHED);
+                                       0);
                if (ret) {
                        mlog_errno(ret);
                        goto out;
@@ -2426,7 +2426,7 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode,
 
        for (i = 0; i < num_buckets; i++, blkno += blk_per_bucket) {
                ret = ocfs2_read_blocks(inode, blkno, blk_per_bucket,
-                                       bucket.bhs, OCFS2_BH_CACHED);
+                                       bucket.bhs, 0);
                if (ret) {
                        mlog_errno(ret);
                        goto out;
@@ -2694,7 +2694,7 @@ static int ocfs2_xattr_update_xattr_search(struct inode *inode,
                        ret = ocfs2_read_blocks(inode,
                                        xs->bucket.bhs[0]->b_blocknr + 1,
                                        blk_per_bucket - 1, &xs->bucket.bhs[1],
-                                       OCFS2_BH_CACHED);
+                                       0);
                        if (ret) {
                                mlog_errno(ret);
                                return ret;
@@ -2898,8 +2898,7 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
        if (!bhs)
                return -ENOMEM;
 
-       ret = ocfs2_read_blocks(inode, blkno, blk_per_bucket, bhs,
-                               OCFS2_BH_CACHED);
+       ret = ocfs2_read_blocks(inode, blkno, blk_per_bucket, bhs, 0);
        if (ret)
                goto out;
 
@@ -3153,8 +3152,7 @@ static int ocfs2_read_xattr_bucket(struct inode *inode,
 
        if (!new)
                return ocfs2_read_blocks(inode, blkno,
-                                        blk_per_bucket, bhs,
-                                        OCFS2_BH_CACHED);
+                                        blk_per_bucket, bhs, 0);
 
        for (i = 0; i < blk_per_bucket; i++) {
                bhs[i] = sb_getblk(inode->i_sb, blkno + i);
@@ -4101,7 +4099,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
                ret = ocfs2_read_blocks(inode,
                                        xs->bucket.bhs[0]->b_blocknr + 1,
                                        blk_per_bucket - 1, &xs->bucket.bhs[1],
-                                       OCFS2_BH_CACHED);
+                                       0);
                if (ret) {
                        mlog_errno(ret);
                        goto out;
index 3d3e16631472212bca09147967724161e2f4022d..a97b477ac0fc38b4e691f6c980b06cc6d921e05a 100644 (file)
@@ -275,16 +275,6 @@ adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev)
        id = data[0x1fc] & 15;
        put_dev_sector(sect);
 
-#ifdef CONFIG_BLK_DEV_MFM
-       if (MAJOR(bdev->bd_dev) == MFM_ACORN_MAJOR) {
-               extern void xd_set_geometry(struct block_device *,
-                       unsigned char, unsigned char, unsigned int);
-               xd_set_geometry(bdev, dr->secspertrack, heads, 1);
-               invalidate_bh_lrus();
-               truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
-       }
-#endif
-
        /*
         * Work out start of non-adfs partition.
         */
index 7408227c49c91cefed99f861a90a8bbb85e8b346..fbeb2f372a93dba06f0d9aab1cfb438389a5668e 100644 (file)
@@ -538,10 +538,23 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
                sector_t from = state->parts[p].from;
                if (!size)
                        continue;
+               if (from >= get_capacity(disk)) {
+                       printk(KERN_WARNING
+                              "%s: p%d ignored, start %llu is behind the end of the disk\n",
+                              disk->disk_name, p, (unsigned long long) from);
+                       continue;
+               }
                if (from + size > get_capacity(disk)) {
+                       /*
+                        * we can not ignore partitions of broken tables
+                        * created by for example camera firmware, but we
+                        * limit them to the end of the disk to avoid
+                        * creating invalid block devices
+                        */
                        printk(KERN_WARNING
-                               "%s: p%d exceeds device capacity\n",
-                               disk->disk_name, p);
+                              "%s: p%d size %llu limited to end of disk\n",
+                              disk->disk_name, p, (unsigned long long) size);
+                       size = get_capacity(disk) - from;
                }
                res = add_partition(disk, p, from, size, state->parts[p].flags);
                if (res) {
index b675a49c182333eb6a38c321d288ca9ae6c4f46b..59ea42e1ef03a0a4acdf3f73283d913b740415fd 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/blkdev.h>
 #include <linux/hugetlb.h>
 #include <linux/jiffies.h>
-#include <linux/sysrq.h>
 #include <linux/vmalloc.h>
 #include <linux/crash_dump.h>
 #include <linux/pid_namespace.h>
@@ -704,28 +703,6 @@ static int execdomains_read_proc(char *page, char **start, off_t off,
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-#ifdef CONFIG_MAGIC_SYSRQ
-/*
- * 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, NULL, 0);
-       }
-       return count;
-}
-
-static const struct file_operations proc_sysrq_trigger_operations = {
-       .write          = write_sysrq_trigger,
-};
-#endif
-
 #ifdef CONFIG_PROC_PAGE_MONITOR
 #define KPMSIZE sizeof(u64)
 #define KPMMASK (KPMSIZE - 1)
@@ -934,7 +911,4 @@ void __init proc_misc_init(void)
 #ifdef CONFIG_PROC_VMCORE
        proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
 #endif
-#ifdef CONFIG_MAGIC_SYSRQ
-       proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
-#endif
 }
index b9dbeeca7049451e66281a1561da4f36a913703a..37173fa07d1532c854fef231bda9a0744ce81374 100644 (file)
@@ -8,8 +8,6 @@
 
 /* proc info support a la one created by Sizif@Botik.RU for PGC */
 
-/* $Id: procfs.c,v 1.1.8.2 2001/07/15 17:08:42 god Exp $ */
-
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/seq_file.h>
@@ -621,7 +619,6 @@ int reiserfs_global_version_in_proc(char *buffer, char **start,
 #endif
 
 /*
- * $Log: procfs.c,v $
  * Revision 1.1.8.2  2001/07/15 17:08:42  god
  *  . use get_super() in procfs.c
  *  . remove remove_save_link() from reiserfs_do_truncate()
index bb3cb5b7cdb2479d1b68b9eb2fa2521e54810490..ad92461cbfc3cadb5b2dcbb32725f108cc0f08a9 100644 (file)
@@ -155,7 +155,7 @@ static struct dentry *get_xa_file_dentry(const struct inode *inode,
        xadir = open_xa_dir(inode, flags);
        if (IS_ERR(xadir)) {
                return ERR_CAST(xadir);
-       } else if (xadir && !xadir->d_inode) {
+       } else if (!xadir->d_inode) {
                dput(xadir);
                return ERR_PTR(-ENODATA);
        }
index 006fc64227ddb16b051b85b0a959cfee7bd652a8..66f6e58a7e4bb1a52590f4eecbb4094647c61c4f 100644 (file)
@@ -61,6 +61,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
        int size = dentry->d_inode->i_size;
        loff_t offs = *off;
        int count = min_t(size_t, bytes, PAGE_SIZE);
+       char *temp;
 
        if (size) {
                if (offs > size)
@@ -69,23 +70,33 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
                        count = size - offs;
        }
 
+       temp = kmalloc(count, GFP_KERNEL);
+       if (!temp)
+               return -ENOMEM;
+
        mutex_lock(&bb->mutex);
 
        count = fill_read(dentry, bb->buffer, offs, count);
-       if (count < 0)
-               goto out_unlock;
+       if (count < 0) {
+               mutex_unlock(&bb->mutex);
+               goto out_free;
+       }
 
-       if (copy_to_user(userbuf, bb->buffer, count)) {
+       memcpy(temp, bb->buffer, count);
+
+       mutex_unlock(&bb->mutex);
+
+       if (copy_to_user(userbuf, temp, count)) {
                count = -EFAULT;
-               goto out_unlock;
+               goto out_free;
        }
 
        pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
 
        *off = offs + count;
 
- out_unlock:
-       mutex_unlock(&bb->mutex);
+ out_free:
+       kfree(temp);
        return count;
 }
 
@@ -118,6 +129,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
        int size = dentry->d_inode->i_size;
        loff_t offs = *off;
        int count = min_t(size_t, bytes, PAGE_SIZE);
+       char *temp;
 
        if (size) {
                if (offs > size)
@@ -126,19 +138,27 @@ static ssize_t write(struct file *file, const char __user *userbuf,
                        count = size - offs;
        }
 
-       mutex_lock(&bb->mutex);
+       temp = kmalloc(count, GFP_KERNEL);
+       if (!temp)
+               return -ENOMEM;
 
-       if (copy_from_user(bb->buffer, userbuf, count)) {
+       if (copy_from_user(temp, userbuf, count)) {
                count = -EFAULT;
-               goto out_unlock;
+               goto out_free;
        }
 
+       mutex_lock(&bb->mutex);
+
+       memcpy(bb->buffer, temp, count);
+
        count = flush_write(dentry, bb->buffer, offs, count);
+       mutex_unlock(&bb->mutex);
+
        if (count > 0)
                *off = offs + count;
 
- out_unlock:
-       mutex_unlock(&bb->mutex);
+out_free:
+       kfree(temp);
        return count;
 }
 
index aedaeba82ae5503a41cbd6ee366601ecb67ae31b..3a05a596e3b4de91dcb522401441b8dc8d959aa9 100644 (file)
@@ -370,17 +370,17 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
        memset(acxt, 0, sizeof(*acxt));
        acxt->parent_sd = parent_sd;
 
-       /* Lookup parent inode.  inode initialization and I_NEW
-        * clearing are protected by sysfs_mutex.  By grabbing it and
-        * looking up with _nowait variant, inode state can be
-        * determined reliably.
+       /* Lookup parent inode.  inode initialization is protected by
+        * sysfs_mutex, so inode existence can be determined by
+        * looking up inode while holding sysfs_mutex.
         */
        mutex_lock(&sysfs_mutex);
 
-       inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
-                               parent_sd);
+       inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
+                        parent_sd);
+       if (inode) {
+               WARN_ON(inode->i_state & I_NEW);
 
-       if (inode && !(inode->i_state & I_NEW)) {
                /* parent inode available */
                acxt->parent_inode = inode;
 
@@ -393,8 +393,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
                        mutex_lock(&inode->i_mutex);
                        mutex_lock(&sysfs_mutex);
                }
-       } else
-               iput(inode);
+       }
 }
 
 /**
@@ -636,6 +635,7 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
 
        return sd;
 }
+EXPORT_SYMBOL_GPL(sysfs_get_dirent);
 
 static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
                      const char *name, struct sysfs_dirent **p_sd)
@@ -829,16 +829,12 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
        if (!new_dentry)
                goto out_unlock;
 
-       /* rename kobject and sysfs_dirent */
+       /* rename sysfs_dirent */
        error = -ENOMEM;
        new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
        if (!new_name)
                goto out_unlock;
 
-       error = kobject_set_name(kobj, "%s", new_name);
-       if (error)
-               goto out_unlock;
-
        dup_name = sd->s_name;
        sd->s_name = new_name;
 
index c9e4e5091da14c24b185b67419f3207188150f96..1f4a3f877262f5f6fbf34085f688e50b42471c8e 100644 (file)
 #include <linux/poll.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/limits.h>
 #include <asm/uaccess.h>
 
 #include "sysfs.h"
 
+/* used in crash dumps to help with debugging */
+static char last_sysfs_file[PATH_MAX];
+void sysfs_printk_last_file(void)
+{
+       printk(KERN_EMERG "last sysfs file: %s\n", last_sysfs_file);
+}
+
 /*
  * There's one sysfs_buffer for each open file and one
  * sysfs_open_dirent for each sysfs_dirent with one or more open
@@ -328,6 +336,11 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
        struct sysfs_buffer *buffer;
        struct sysfs_ops *ops;
        int error = -EACCES;
+       char *p;
+
+       p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file));
+       if (p)
+               memmove(last_sysfs_file, p, strlen(p) + 1);
 
        /* need attr_sd for attr and ops, its parent for kobj */
        if (!sysfs_get_active_two(attr_sd))
@@ -440,7 +453,23 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
        return POLLERR|POLLPRI;
 }
 
-void sysfs_notify(struct kobject *k, char *dir, char *attr)
+void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+       struct sysfs_open_dirent *od;
+
+       spin_lock(&sysfs_open_dirent_lock);
+
+       od = sd->s_attr.open;
+       if (od) {
+               atomic_inc(&od->event);
+               wake_up_interruptible(&od->poll);
+       }
+
+       spin_unlock(&sysfs_open_dirent_lock);
+}
+EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
+
+void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
 {
        struct sysfs_dirent *sd = k->sd;
 
@@ -450,19 +479,8 @@ void sysfs_notify(struct kobject *k, char *dir, char *attr)
                sd = sysfs_find_dirent(sd, dir);
        if (sd && attr)
                sd = sysfs_find_dirent(sd, attr);
-       if (sd) {
-               struct sysfs_open_dirent *od;
-
-               spin_lock(&sysfs_open_dirent_lock);
-
-               od = sd->s_attr.open;
-               if (od) {
-                       atomic_inc(&od->event);
-                       wake_up_interruptible(&od->poll);
-               }
-
-               spin_unlock(&sysfs_open_dirent_lock);
-       }
+       if (sd)
+               sysfs_notify_dirent(sd);
 
        mutex_unlock(&sysfs_mutex);
 }
index 14f0023984d74d6a51dedc0791fdfab53f2d5cc4..ab343e371d64682f678646ed02615171e73b2d31 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 #include "sysfs.h"
 
@@ -115,3 +116,17 @@ out_err:
        sysfs_dir_cachep = NULL;
        goto out;
 }
+
+#undef sysfs_get
+struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+       return __sysfs_get(sd);
+}
+EXPORT_SYMBOL_GPL(sysfs_get);
+
+#undef sysfs_put
+void sysfs_put(struct sysfs_dirent *sd)
+{
+       __sysfs_put(sd);
+}
+EXPORT_SYMBOL_GPL(sysfs_put);
index a5db496f71c717ce63073440a3c9a23138b67d47..93c6d6b27c4ded5596c783ac1bdbe4e4b2590bbd 100644 (file)
@@ -124,7 +124,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
                        struct sysfs_dirent **p_sd);
 void sysfs_remove_subdir(struct sysfs_dirent *sd);
 
-static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
 {
        if (sd) {
                WARN_ON(!atomic_read(&sd->s_count));
@@ -132,12 +132,14 @@ static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
        }
        return sd;
 }
+#define sysfs_get(sd) __sysfs_get(sd)
 
-static inline void sysfs_put(struct sysfs_dirent *sd)
+static inline void __sysfs_put(struct sysfs_dirent *sd)
 {
        if (sd && atomic_dec_and_test(&sd->s_count))
                release_sysfs_dirent(sd);
 }
+#define sysfs_put(sd) __sysfs_put(sd)
 
 /*
  * inode.c
index 7227b2efef22ec5c0417b08a7464456c06647400..e39013619b2619317a77cb8e1ceb3aee05de033f 100644 (file)
@@ -1323,7 +1323,7 @@ xfs_fs_remount(
        "XFS: mount option \"%s\" not supported for remount\n", p);
                        return -EINVAL;
 #else
-                       return 0;
+                       break;
 #endif
                }
        }
index 57ab9e9d7593e6213ff2342f55d2dbaaab92ff80..74a9617776a80f728b874ab47f58a5f124d00996 100644 (file)
@@ -467,7 +467,7 @@ struct acpi_integer_overlay {
 /*
  * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header,
  * define it now. This is the case where there the compiler does not support
- * a __FUNCTION__ macro or equivalent.
+ * a __func__ macro or equivalent.
  */
 #ifndef ACPI_GET_FUNCTION_NAME
 #define ACPI_GET_FUNCTION_NAME          _acpi_function_name
@@ -475,12 +475,12 @@ struct acpi_integer_overlay {
  * The Name parameter should be the procedure name as a quoted string.
  * The function name is also used by the function exit macros below.
  * Note: (const char) is used to be compatible with the debug interfaces
- * and macros such as __FUNCTION__.
+ * and macros such as __func__.
  */
 #define ACPI_FUNCTION_NAME(name)       static const char _acpi_function_name[] = #name;
 
 #else
-/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */
+/* Compiler supports __func__ (or equivalent) -- Ignore this macro */
 
 #define ACPI_FUNCTION_NAME(name)
 #endif
index 8996dba90cd91bbe07b084baf84bd52b46d2fde8..8e2cdc57b1974f5430b4d39fe681090f9ffd0441 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Function name is used for debug output. Non-ANSI, compiler-dependent */
 
-#define ACPI_GET_FUNCTION_NAME          __FUNCTION__
+#define ACPI_GET_FUNCTION_NAME          __func__
 
 /*
  * This macro is used to tag functions as "printf-like" because
index 001f64ad11e8c5e002003427b6833c402a3f26d7..f0d17fbc81bae8a53c33ae6473661cfe7ea108b7 100644 (file)
@@ -88,6 +88,6 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif
index 9fb946bb7dc98c26cc8b43b2e3686647238e0d86..7279ec07d62e32007f91a01bfe58a20014283a4d 100644 (file)
@@ -137,6 +137,6 @@ do {                                                                                        \
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif
index 839a2fbffa0f34c8c428b6a5793a407749e69ac8..6c61c05b2e0cfe36844b1d7466879b9f4c4f4f69 100644 (file)
@@ -13,7 +13,7 @@
 #define _ASM_UNALIGNED_H
 
 #include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/be_struct.h>
 #include <linux/unaligned/generic.h>
 
 #define get_unaligned  __get_unaligned_be
index edc6ba82e090961a841cd37b54cb6abc0311b4d7..0f6dabd4b5175488081fc8395a30b9a5d5e5f217 100644 (file)
@@ -22,7 +22,7 @@ struct bug_entry {
 
 #ifndef HAVE_ARCH_BUG
 #define BUG() do { \
-       printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
+       printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
        panic("BUG!"); \
 } while (0)
 #endif
index 0f99ad38b012f93ef10ccb5b0f9105b4e7f8daab..81797ec9ab2917413ba28d166adb267726c8f177 100644 (file)
@@ -35,11 +35,17 @@ struct module;
  * @label: for diagnostics
  * @dev: optional device providing the GPIOs
  * @owner: helps prevent removal of modules exporting active GPIOs
+ * @request: optional hook for chip-specific activation, such as
+ *     enabling module power and clock; may sleep
+ * @free: optional hook for chip-specific deactivation, such as
+ *     disabling module power and clock; may sleep
  * @direction_input: configures signal "offset" as input, or returns error
  * @get: returns value for signal "offset"; for output signals this
  *     returns either the value actually sensed, or zero
  * @direction_output: configures signal "offset" as output, or returns error
  * @set: assigns output value for signal "offset"
+ * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
+ *     implementation may not sleep
  * @dbg_show: optional routine to show contents in debugfs; default code
  *     will be used when this is omitted, but custom code can show extra
  *     state (such as pullup/pulldown configuration).
@@ -61,10 +67,15 @@ struct module;
  * is calculated by subtracting @base from the gpio number.
  */
 struct gpio_chip {
-       char                    *label;
+       const char              *label;
        struct device           *dev;
        struct module           *owner;
 
+       int                     (*request)(struct gpio_chip *chip,
+                                               unsigned offset);
+       void                    (*free)(struct gpio_chip *chip,
+                                               unsigned offset);
+
        int                     (*direction_input)(struct gpio_chip *chip,
                                                unsigned offset);
        int                     (*get)(struct gpio_chip *chip,
@@ -73,6 +84,10 @@ struct gpio_chip {
                                                unsigned offset, int value);
        void                    (*set)(struct gpio_chip *chip,
                                                unsigned offset, int value);
+
+       int                     (*to_irq)(struct gpio_chip *chip,
+                                               unsigned offset);
+
        void                    (*dbg_show)(struct seq_file *s,
                                                struct gpio_chip *chip);
        int                     base;
@@ -112,6 +127,7 @@ extern void __gpio_set_value(unsigned gpio, int value);
 
 extern int __gpio_cansleep(unsigned gpio);
 
+extern int __gpio_to_irq(unsigned gpio);
 
 #ifdef CONFIG_GPIO_SYSFS
 
index 7440a0dceddba276b59199d14e64a1ee2f232b36..74c5faf26c053a137768d5f4224d466945bc3253 100644 (file)
        CPU_DISCARD(init.data)                                          \
        CPU_DISCARD(init.rodata)                                        \
        MEM_DISCARD(init.data)                                          \
-       MEM_DISCARD(init.rodata)
+       MEM_DISCARD(init.rodata)                                        \
+       /* implement dynamic printk debug */                            \
+       VMLINUX_SYMBOL(__start___verbose_strings) = .;                  \
+       *(__verbose_strings)                                            \
+       VMLINUX_SYMBOL(__stop___verbose_strings) = .;                   \
+       . = ALIGN(8);                                                   \
+       VMLINUX_SYMBOL(__start___verbose) = .;                          \
+       *(__verbose)                                                    \
+       VMLINUX_SYMBOL(__stop___verbose) = .;
 
 #define INIT_TEXT                                                      \
        *(.init.text)                                                   \
diff --git a/include/asm-h8300/timer.h b/include/asm-h8300/timer.h
new file mode 100644 (file)
index 0000000..def8046
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __H8300_TIMER_H
+#define __H8300_TIMER_H
+
+void h8300_timer_tick(void);
+void h8300_timer_setup(void);
+void h8300_gettod(unsigned int *year, unsigned int *mon, unsigned int *day,
+                  unsigned int *hour, unsigned int *min, unsigned int *sec);
+
+#define TIMER_FREQ (CONFIG_CPU_CLOCK*10000) /* Timer input freq. */
+
+#define calc_param(cnt, div, rate, limit)                      \
+do {                                                           \
+       cnt = TIMER_FREQ / HZ;                                  \
+       for (div = 0; div < ARRAY_SIZE(divide_rate); div++) {   \
+               if (rate[div] == 0)                             \
+                       continue;                               \
+               if ((cnt / rate[div]) > limit)                  \
+                       break;                                  \
+       }                                                       \
+       if (div == ARRAY_SIZE(divide_rate))                     \
+               panic("Timer counter overflow");                \
+       cnt /= divide_rate[div];                                \
+} while(0)
+
+#endif
index 67bcd77494a5697942ae2363f19478bdc7fd2197..0cc34c94bf2bf26a087a73a11ea32302d48eebf6 100644 (file)
@@ -129,6 +129,6 @@ typedef elf_fpreg_t elf_fpregset_t;
    intent than poking at uname or /proc/cpuinfo.  */
 #define ELF_PLATFORM   (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif  /* _ASM_M32R__ELF_H */
index 14ea42152b9785c75925414b7a971212e122604e..0b0f49eb876b11db0ce7eb6cd1703be2657fbd54 100644 (file)
@@ -114,6 +114,6 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 
 #endif
index 256a70466ca4385ca9478303131e29c88129c4b6..bf09f8bb392eef17bf41441050b5adb6e9920d0b 100644 (file)
@@ -141,7 +141,7 @@ do {                                                \
 #define ELF_PLATFORM  (NULL)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
 #endif
 
 #endif /* _ASM_ELF_H */
index d0a4a82628181578a943ae082c60ae8b63959411..7fa675799e6d2cad21304698f7dec833a12224e7 100644 (file)
@@ -236,7 +236,7 @@ typedef unsigned long elf_greg_t;
 
 #define ELF_PLATFORM  ("PARISC\0")
 
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
        current->personality = PER_LINUX; \
        current->thread.map_base = DEFAULT_MAP_BASE; \
        current->thread.task_size = DEFAULT_TASK_SIZE \
index 23d6893e8617d6ccfa0deb9819587d6f3d1452f6..d0da9d7c53716fc294fd1d1c26759d03da784469 100644 (file)
@@ -86,7 +86,7 @@ extern long elf_aux_hwcap;
 extern char * elf_aux_platform;
 #define ELF_PLATFORM (elf_aux_platform)
 
-#define SET_PERSONALITY(ex, ibcs2) do { } while (0)
+#define SET_PERSONALITY(ex) do { } while (0)
 
 extern unsigned long vsyscall_ehdr;
 extern unsigned long vsyscall_end;
index d3b90b7ac3e9820921272b12642f193803b142f5..af9463cd8ce51f936af61c14d8ce217bf3eb5eec 100644 (file)
@@ -5,7 +5,7 @@
 extern long elf_aux_hwcap;
 #define ELF_HWCAP (elf_aux_hwcap)
 
-#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+#define SET_PERSONALITY(ex) do ; while(0)
 
 #define ELF_EXEC_PAGESIZE 4096
 
index 3b2d5224a7e166947be5ce2baa9ae720e696a7e3..6e8a9195e95266ff55276e7de633782e970a646b 100644 (file)
@@ -114,6 +114,6 @@ extern long elf_aux_hwcap;
 
 #define ELF_PLATFORM "x86_64"
 
-#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+#define SET_PERSONALITY(ex) do ; while(0)
 
 #endif
index 5c4745bec9061c0febdfb21ab4534c89c8f354f9..26bc15f01e78a3faa7d7b4b540ab57741e3d94da 100644 (file)
@@ -186,7 +186,7 @@ do {                                                        \
        set_fs(USER_DS);                                \
 } while (0)
 
-#define COMPAT_SET_PERSONALITY(ex, ibcs2)              \
+#define COMPAT_SET_PERSONALITY(ex)                     \
 do {                                                   \
        if (test_thread_flag(TIF_IA32))                 \
                clear_thread_flag(TIF_ABI_PENDING);     \
@@ -267,7 +267,7 @@ extern int force_personality32;
    For the moment, we have only optimizations for the Intel generations,
    but that could change... */
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality_64bit()
+#define SET_PERSONALITY(ex) set_personality_64bit()
 
 /*
  * An executable for which elf_read_implies_exec() returns TRUE will
index bd2c44d1f7ac356f6e09a277763b9d1d585454c2..aae50c2fb303db35d3bab0f2cfdd1a854f1b4fb2 100644 (file)
@@ -171,7 +171,7 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
                        int new_apicid = cpu_to_logical_apicid(cpu);
                        if (apicid_cluster(apicid) !=
                                        apicid_cluster(new_apicid)){
-                               printk ("%s: Not a valid mask!\n",__FUNCTION__);
+                               printk ("%s: Not a valid mask!\n", __func__);
 #if defined CONFIG_ES7000_CLUSTERED_APIC
                                return 0xFF;
 #else
index 546ad3110feaef59c2a607e98593d8e38f17b272..961e746da977d470092b9ab912cf1d3f2531a4b7 100644 (file)
@@ -8,7 +8,7 @@ extern int force_iommu, no_iommu;
 extern int iommu_detected;
 extern int dmar_disabled;
 
-extern unsigned long iommu_num_pages(unsigned long addr, unsigned long len);
+extern unsigned long iommu_nr_pages(unsigned long addr, unsigned long len);
 
 #ifdef CONFIG_GART_IOMMU
 extern int gart_iommu_aperture;
index 182f9d4c570f5e9f33d3cd5b1b161a37d313fe36..88a53b1a17f03f486e9a22a138b30b2e422e6544 100644 (file)
 #ifdef CONFIG_X86_64
 #define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
 #else
+/*
+ * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
+ * bits are combined, this will alow user to access the high address mapped
+ * VDSO in the presence of CONFIG_COMPAT_VDSO
+ */
 #define PTE_IDENT_ATTR  0x003          /* PRESENT+RW */
-#define PDE_IDENT_ATTR  0x063          /* PRESENT+RW+DIRTY+ACCESSED */
+#define PDE_IDENT_ATTR  0x067          /* PRESENT+RW+USER+DIRTY+ACCESSED */
 #define PGD_IDENT_ATTR  0x001          /* PRESENT (no other attributes) */
 #endif
 
index c5b2e4b10358dd6beda71fb8b5a318d9ee341dff..394b00bb5e72542b3bfd4ecc2efbee58157cf3a9 100644 (file)
@@ -160,7 +160,7 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
                        int new_apicid = cpu_to_logical_apicid(cpu);
                        if (apicid_cluster(apicid) !=
                                        apicid_cluster(new_apicid)){
-                               printk ("%s: Not a valid mask!\n",__FUNCTION__);
+                               printk ("%s: Not a valid mask!\n", __func__);
                                return 0xFF;
                        }
                        apicid = apicid | new_apicid;
index ca6e5101a2cba6fb021fec6891193653660ecd64..c3f53e755ca5c16fabff550b1c7859c6521c9e17 100644 (file)
@@ -189,7 +189,7 @@ typedef struct {
 #endif
 } elf_xtregs_t;
 
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
 
 struct task_struct;
 
index 282a504bd1dbefed45609eae5c5bf02edd1bc49b..bf9aca548f14a931f33e35bfed8a8efb4036e8e8 100644 (file)
@@ -107,6 +107,7 @@ header-y += keyctl.h
 header-y += limits.h
 header-y += magic.h
 header-y += major.h
+header-y += map_to_7segment.h
 header-y += matroxfb.h
 header-y += meye.h
 header-y += minix_fs.h
index 09b276c35227f43ef120d3e729dc0d27f68e303e..f6b8cf99b596a30820215766fb7e680dedf7e6e1 100644 (file)
@@ -204,12 +204,21 @@ struct kioctx {
 /* prototypes */
 extern unsigned aio_max_size;
 
+#ifdef CONFIG_AIO
 extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb);
 extern int aio_put_req(struct kiocb *iocb);
 extern void kick_iocb(struct kiocb *iocb);
 extern int aio_complete(struct kiocb *iocb, long res, long res2);
 struct mm_struct;
 extern void exit_aio(struct mm_struct *mm);
+#else
+static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; }
+static inline int aio_put_req(struct kiocb *iocb) { return 0; }
+static inline void kick_iocb(struct kiocb *iocb) { }
+static inline int aio_complete(struct kiocb *iocb, long res, long res2) { return 0; }
+struct mm_struct;
+static inline void exit_aio(struct mm_struct *mm) { }
+#endif /* CONFIG_AIO */
 
 #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
 
diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h
new file mode 100644 (file)
index 0000000..f4d05cc
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
+ * Copyright 2008 Ian Kent <raven@themaw.net>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ */
+
+#ifndef _LINUX_AUTO_DEV_IOCTL_H
+#define _LINUX_AUTO_DEV_IOCTL_H
+
+#include <linux/types.h>
+
+#define AUTOFS_DEVICE_NAME             "autofs"
+
+#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
+
+#define AUTOFS_DEVID_LEN               16
+
+#define AUTOFS_DEV_IOCTL_SIZE          sizeof(struct autofs_dev_ioctl)
+
+/*
+ * An ioctl interface for autofs mount point control.
+ */
+
+/*
+ * All the ioctls use this structure.
+ * When sending a path size must account for the total length
+ * of the chunk of memory otherwise is is the size of the
+ * structure.
+ */
+
+struct autofs_dev_ioctl {
+       __u32 ver_major;
+       __u32 ver_minor;
+       __u32 size;             /* total size of data passed in
+                                * including this struct */
+       __s32 ioctlfd;          /* automount command fd */
+
+       __u32 arg1;             /* Command parameters */
+       __u32 arg2;
+
+       char path[0];
+};
+
+static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
+{
+       in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
+       in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
+       in->size = sizeof(struct autofs_dev_ioctl);
+       in->ioctlfd = -1;
+       in->arg1 = 0;
+       in->arg2 = 0;
+       return;
+}
+
+/*
+ * If you change this make sure you make the corresponding change
+ * to autofs-dev-ioctl.c:lookup_ioctl()
+ */
+enum {
+       /* Get various version info */
+       AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
+       AUTOFS_DEV_IOCTL_PROTOVER_CMD,
+       AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
+
+       /* Open mount ioctl fd */
+       AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
+
+       /* Close mount ioctl fd */
+       AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
+
+       /* Mount/expire status returns */
+       AUTOFS_DEV_IOCTL_READY_CMD,
+       AUTOFS_DEV_IOCTL_FAIL_CMD,
+
+       /* Activate/deactivate autofs mount */
+       AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
+       AUTOFS_DEV_IOCTL_CATATONIC_CMD,
+
+       /* Expiry timeout */
+       AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
+
+       /* Get mount last requesting uid and gid */
+       AUTOFS_DEV_IOCTL_REQUESTER_CMD,
+
+       /* Check for eligible expire candidates */
+       AUTOFS_DEV_IOCTL_EXPIRE_CMD,
+
+       /* Request busy status */
+       AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
+
+       /* Check if path is a mountpoint */
+       AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
+};
+
+#define AUTOFS_IOCTL 0x93
+
+#define AUTOFS_DEV_IOCTL_VERSION \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_PROTOVER \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_PROTOSUBVER \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_OPENMOUNT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_READY \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_FAIL \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_SETPIPEFD \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_CATATONIC \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_TIMEOUT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_REQUESTER \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_EXPIRE \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_ASKUMOUNT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \
+       _IOWR(AUTOFS_IOCTL, \
+             AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
+
+#endif /* _LINUX_AUTO_DEV_IOCTL_H */
index b785c6f8644dc28ca92793f96c31ab0b53ab4c85..2253716d4b92227a2d6deb49a20b53b7088ece9d 100644 (file)
 #define AUTOFS_MIN_PROTO_VERSION       3
 #define AUTOFS_MAX_PROTO_VERSION       5
 
-#define AUTOFS_PROTO_SUBVERSION                0
+#define AUTOFS_PROTO_SUBVERSION                1
 
 /* Mask for expire behaviour */
 #define AUTOFS_EXP_IMMEDIATE           1
 #define AUTOFS_EXP_LEAVES              2
 
+#define AUTOFS_TYPE_ANY                        0x0000
+#define AUTOFS_TYPE_INDIRECT           0x0001
+#define AUTOFS_TYPE_DIRECT             0x0002
+#define AUTOFS_TYPE_OFFSET             0x0004
+
 /* Daemon notification packet types */
 enum autofs_notify {
        NFY_NONE,
index 826f62350805ed782976008db013203061306744..7394b5b349ffc82c2ea42e51188dc3839229fed1 100644 (file)
@@ -36,6 +36,10 @@ struct linux_binprm{
        unsigned long p; /* current top of mem */
        unsigned int sh_bang:1,
                     misc_bang:1;
+#ifdef __alpha__
+       unsigned int taso:1;
+#endif
+       unsigned int recursion_depth;
        struct file * file;
        int e_uid, e_gid;
        kernel_cap_t cap_post_exec_permitted;
@@ -58,6 +62,7 @@ struct linux_binprm{
 #define BINPRM_FLAGS_EXECFD_BIT 1
 #define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT)
 
+#define BINPRM_MAX_RECURSION 4
 
 /*
  * This structure defines the functions that are used to load the binary formats that
index c98dd7cb7076f44484a68643995f10fd1bbc2ff8..30934e4bfaab7b9e3197e0d7410579c0737bf2c7 100644 (file)
@@ -326,7 +326,8 @@ struct cgroup_subsys {
         */
        void (*mm_owner_changed)(struct cgroup_subsys *ss,
                                        struct cgroup *old,
-                                       struct cgroup *new);
+                                       struct cgroup *new,
+                                       struct task_struct *p);
        int subsys_id;
        int active;
        int disabled;
index 5ca8c6fddb56216291e5233c9b37cee09076b269..778777316ea4bc3747983e2c9ed60ed5e1d321dc 100644 (file)
@@ -35,6 +35,8 @@ struct clk;
  * clk_get may return different clock producers depending on @dev.)
  *
  * Drivers must assume that the clock source is not enabled.
+ *
+ * clk_get should not be called from within interrupt context.
  */
 struct clk *clk_get(struct device *dev, const char *id);
 
@@ -76,6 +78,8 @@ unsigned long clk_get_rate(struct clk *clk);
  * Note: drivers must ensure that all clk_enable calls made on this
  * clock source are balanced by clk_disable calls prior to calling
  * this function.
+ *
+ * clk_put should not be called from within interrupt context.
  */
 void clk_put(struct clk *clk);
 
index cf8d11cad5aef24dd99c57c3f7406d9ea4c541d6..f061a1ea1b74d74fa7a3391bb47c6bbdca4d0b3e 100644 (file)
@@ -78,7 +78,6 @@ typedef struct {
        compat_sigset_word      sig[_COMPAT_NSIG_WORDS];
 } compat_sigset_t;
 
-extern int cp_compat_stat(struct kstat *, struct compat_stat __user *);
 extern int get_compat_timespec(struct timespec *, const struct compat_timespec __user *);
 extern int put_compat_timespec(const struct timespec *, struct compat_timespec __user *);
 
@@ -235,6 +234,11 @@ extern int get_compat_itimerspec(struct itimerspec *dst,
 extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
                                 const struct itimerspec *src);
 
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz);
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz);
+
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
 extern int compat_printk(const char *fmt, ...);
index 246937c9cbc780db2cc30b542453d401bcd6c334..987f5912720a2d6ffd6d32a33a062e3b4ef27892 100644 (file)
@@ -90,6 +90,9 @@ int __must_check bus_for_each_drv(struct bus_type *bus,
                                  struct device_driver *start, void *data,
                                  int (*fn)(struct device_driver *, void *));
 
+void bus_sort_breadthfirst(struct bus_type *bus,
+                          int (*compare)(const struct device *a,
+                                         const struct device *b));
 /*
  * Bus notifiers: Get notified of addition/removal of devices
  * and binding/unbinding of drivers to devices.
@@ -502,7 +505,6 @@ extern struct device *device_create(struct class *cls, struct device *parent,
                                    dev_t devt, void *drvdata,
                                    const char *fmt, ...)
                                    __attribute__((format(printf, 5, 6)));
-#define device_create_drvdata  device_create
 extern void device_destroy(struct class *cls, dev_t devt);
 
 /*
@@ -551,7 +553,11 @@ extern const char *dev_driver_string(const struct device *dev);
 #define dev_info(dev, format, arg...)          \
        dev_printk(KERN_INFO , dev , format , ## arg)
 
-#ifdef DEBUG
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#define dev_dbg(dev, format, ...) do { \
+       dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
+       } while (0)
+#elif defined(DEBUG)
 #define dev_dbg(dev, format, arg...)           \
        dev_printk(KERN_DEBUG , dev , format , ## arg)
 #else
@@ -567,6 +573,14 @@ extern const char *dev_driver_string(const struct device *dev);
        ({ if (0) dev_printk(KERN_DEBUG, dev, format, ##arg); 0; })
 #endif
 
+/*
+ * dev_WARN() acts like dev_printk(), but with the key difference
+ * of using a WARN/WARN_ON to get the message out, including the
+ * file/line information and a backtrace.
+ */
+#define dev_WARN(dev, format, arg...) \
+       WARN(1, "Device: %s\n" format, dev_driver_string(dev), ## arg);
+
 /* Create alias, so I can be autoloaded. */
 #define MODULE_ALIAS_CHARDEV(major,minor) \
        MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
index d8989860e4cefba476e8e31566690e4f687e88de..45ea0aa0aeb9e8ca8f48a8d628e60fd32a58a8e7 100644 (file)
@@ -8,8 +8,6 @@
 #ifndef __LINUX_DS1286_H
 #define __LINUX_DS1286_H
 
-#include <asm/ds1286.h>
-
 /**********************************************************************
  * register summary
  **********************************************************************/
diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h
new file mode 100644 (file)
index 0000000..2d528d0
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef _DYNAMIC_PRINTK_H
+#define _DYNAMIC_PRINTK_H
+
+#define DYNAMIC_DEBUG_HASH_BITS 6
+#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
+
+#define TYPE_BOOLEAN 1
+
+#define DYNAMIC_ENABLED_ALL 0
+#define DYNAMIC_ENABLED_NONE 1
+#define DYNAMIC_ENABLED_SOME 2
+
+extern int dynamic_enabled;
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+extern long long dynamic_printk_enabled;
+extern long long dynamic_printk_enabled2;
+
+struct mod_debug {
+       char *modname;
+       char *logical_modname;
+       char *flag_names;
+       int type;
+       int hash;
+       int hash2;
+} __attribute__((aligned(8)));
+
+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
+                                       char *flags, int hash, int hash2);
+
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+extern int unregister_dynamic_debug_module(char *mod_name);
+extern int __dynamic_dbg_enabled_helper(char *modname, int type,
+                                       int value, int hash);
+
+#define __dynamic_dbg_enabled(module, type, value, level, hash)  ({         \
+       int __ret = 0;                                                       \
+       if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) &&       \
+                       (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2))))   \
+                       __ret = __dynamic_dbg_enabled_helper(module, type,   \
+                                                               value, hash);\
+       __ret; })
+
+#define dynamic_pr_debug(fmt, ...) do {                                            \
+       static char mod_name[]                                              \
+       __attribute__((section("__verbose_strings")))                       \
+        = KBUILD_MODNAME;                                                  \
+       static struct mod_debug descriptor                                  \
+       __used                                                              \
+       __attribute__((section("__verbose"), aligned(8))) =                 \
+       { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
+       if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN,             \
+                                               0, 0, DEBUG_HASH))          \
+               printk(KERN_DEBUG KBUILD_MODNAME ":" fmt,                   \
+                               ##__VA_ARGS__);                             \
+       } while (0)
+
+#define dynamic_dev_dbg(dev, format, ...) do {                             \
+       static char mod_name[]                                              \
+       __attribute__((section("__verbose_strings")))                       \
+        = KBUILD_MODNAME;                                                  \
+       static struct mod_debug descriptor                                  \
+       __used                                                              \
+       __attribute__((section("__verbose"), aligned(8))) =                 \
+       { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
+       if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN,             \
+                                               0, 0, DEBUG_HASH))          \
+                       dev_printk(KERN_DEBUG, dev,                         \
+                                       KBUILD_MODNAME ": " format,         \
+                                       ##__VA_ARGS__);                     \
+       } while (0)
+
+#else
+
+static inline int unregister_dynamic_debug_module(const char *mod_name)
+{
+       return 0;
+}
+static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
+                                               int value, int hash)
+{
+       return 0;
+}
+
+#define __dynamic_dbg_enabled(module, type, value, level, hash)  ({ 0; })
+#define dynamic_pr_debug(fmt, ...)  do { } while (0)
+#define dynamic_dev_dbg(dev, format, ...)  do { } while (0)
+#endif
+
+#endif
index 2efe7b863cff361301d4a73c1c4e46338d0b02b1..78c775a83f7cd041acaa872ae455676a06a0e096 100644 (file)
@@ -47,7 +47,7 @@
 #ifdef EXT2FS_DEBUG
 #      define ext2_debug(f, a...)      { \
                                        printk ("EXT2-fs DEBUG (%s, %d): %s:", \
-                                               __FILE__, __LINE__, __FUNCTION__); \
+                                               __FILE__, __LINE__, __func__); \
                                        printk (f, ## a); \
                                        }
 #else
index 8120fa1bc2357008f63c06c78d3304c781bf9341..159d9b476cd7f404c0ae33facd7189e7efe477ad 100644 (file)
@@ -43,7 +43,7 @@
 #define ext3_debug(f, a...)                                            \
        do {                                                            \
                printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:",       \
-                       __FILE__, __LINE__, __FUNCTION__);              \
+                       __FILE__, __LINE__, __func__);          \
                printk (KERN_DEBUG f, ## a);                            \
        } while (0)
 #else
@@ -871,7 +871,7 @@ extern void ext3_update_dynamic_rev (struct super_block *sb);
 #define ext3_std_error(sb, errno)                              \
 do {                                                           \
        if ((errno))                                            \
-               __ext3_std_error((sb), __FUNCTION__, (errno));  \
+               __ext3_std_error((sb), __func__, (errno));      \
 } while (0)
 
 /*
index 8c43b13a02fe1df033f161ab91d69cdd7a389858..cf82d519be408b7b97a2a0edd3e796d5eff8c2b5 100644 (file)
@@ -137,17 +137,17 @@ int __ext3_journal_dirty_metadata(const char *where,
                                handle_t *handle, struct buffer_head *bh);
 
 #define ext3_journal_get_undo_access(handle, bh) \
-       __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh))
+       __ext3_journal_get_undo_access(__func__, (handle), (bh))
 #define ext3_journal_get_write_access(handle, bh) \
-       __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh))
+       __ext3_journal_get_write_access(__func__, (handle), (bh))
 #define ext3_journal_revoke(handle, blocknr, bh) \
-       __ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
+       __ext3_journal_revoke(__func__, (handle), (blocknr), (bh))
 #define ext3_journal_get_create_access(handle, bh) \
-       __ext3_journal_get_create_access(__FUNCTION__, (handle), (bh))
+       __ext3_journal_get_create_access(__func__, (handle), (bh))
 #define ext3_journal_dirty_metadata(handle, bh) \
-       __ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh))
+       __ext3_journal_dirty_metadata(__func__, (handle), (bh))
 #define ext3_journal_forget(handle, bh) \
-       __ext3_journal_forget(__FUNCTION__, (handle), (bh))
+       __ext3_journal_forget(__func__, (handle), (bh))
 
 int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh);
 
@@ -160,7 +160,7 @@ static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks)
 }
 
 #define ext3_journal_stop(handle) \
-       __ext3_journal_stop(__FUNCTION__, (handle))
+       __ext3_journal_stop(__func__, (handle))
 
 static inline handle_t *ext3_journal_current_handle(void)
 {
index 0f0e271f97fa1f0fa7248cafc9c579e8be20fe00..4d078e99c01799ec31ecc3f2387d7305e806b46d 100644 (file)
@@ -154,8 +154,13 @@ struct fw_cdev_event_iso_interrupt {
  * @request:       Valid if @common.type == %FW_CDEV_EVENT_REQUEST
  * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT
  *
- * Convenience union for userspace use.  Events could be read(2) into a char
- * buffer and then cast to this union for further processing.
+ * Convenience union for userspace use.  Events could be read(2) into an
+ * appropriately aligned char buffer and then cast to this union for further
+ * processing.  Note that for a request, response or iso_interrupt event,
+ * the data[] or header[] may make the size of the full event larger than
+ * sizeof(union fw_cdev_event).  Also note that if you attempt to read(2)
+ * an event into a buffer that is not large enough for it, the data that does
+ * not fit will be discarded so that the next read(2) will return a new event.
  */
 union fw_cdev_event {
        struct fw_cdev_event_common common;
index f64e29c0ef3f57be1b03aeb0703fe30f58ffbbeb..0cd825f7363a7aa61005b53eb658b7e3dfa66b3d 100644 (file)
@@ -146,10 +146,11 @@ static inline void gameport_unpin_driver(struct gameport *gameport)
        mutex_unlock(&gameport->drv_mutex);
 }
 
-void __gameport_register_driver(struct gameport_driver *drv, struct module *owner);
-static inline void gameport_register_driver(struct gameport_driver *drv)
+int __gameport_register_driver(struct gameport_driver *drv,
+                               struct module *owner, const char *mod_name);
+static inline int __must_check gameport_register_driver(struct gameport_driver *drv)
 {
-       __gameport_register_driver(drv, THIS_MODULE);
+       return __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
 }
 
 void gameport_unregister_driver(struct gameport_driver *drv);
index 730a20b83576b4ab39d81810085c20d61eec0225..e10c49a5b96e9ed300d670871af2edbaaf23add1 100644 (file)
@@ -8,6 +8,7 @@
 
 #else
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 
@@ -32,6 +33,8 @@ static inline int gpio_request(unsigned gpio, const char *label)
 
 static inline void gpio_free(unsigned gpio)
 {
+       might_sleep();
+
        /* GPIO can never have been requested */
        WARN_ON(1);
 }
index 75ae6d8aba4fff5167faf5e8b570f78956ccef91..4c4e57d1f19d74c245c7e70e09c5e9428f838089 100644 (file)
@@ -570,7 +570,6 @@ struct i2o_controller {
 #endif
        spinlock_t lock;        /* lock for controller
                                   configuration */
-
        void *driver_data[I2O_MAX_DRIVERS];     /* storage for drivers */
 };
 
@@ -691,289 +690,22 @@ static inline u32 i2o_dma_high(dma_addr_t dma_addr)
 };
 #endif
 
-/**
- *     i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
- *     @c: I2O controller for which the calculation should be done
- *     @body_size: maximum body size used for message in 32-bit words.
- *
- *     Return the maximum number of SG elements in a SG list.
- */
-static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
-{
-       i2o_status_block *sb = c->status_block.virt;
-       u16 sg_count =
-           (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
-           body_size;
-
-       if (c->pae_support) {
-               /*
-                * for 64-bit a SG attribute element must be added and each
-                * SG element needs 12 bytes instead of 8.
-                */
-               sg_count -= 2;
-               sg_count /= 3;
-       } else
-               sg_count /= 2;
-
-       if (c->short_req && (sg_count > 8))
-               sg_count = 8;
-
-       return sg_count;
-};
-
-/**
- *     i2o_dma_map_single - Map pointer to controller and fill in I2O message.
- *     @c: I2O controller
- *     @ptr: pointer to the data which should be mapped
- *     @size: size of data in bytes
- *     @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- *     @sg_ptr: pointer to the SG list inside the I2O message
- *
- *     This function does all necessary DMA handling and also writes the I2O
- *     SGL elements into the I2O message. For details on DMA handling see also
- *     dma_map_single(). The pointer sg_ptr will only be set to the end of the
- *     SG list if the allocation was successful.
- *
- *     Returns DMA address which must be checked for failures using
- *     dma_mapping_error().
- */
-static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
+extern u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size);
+extern dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
                                            size_t size,
                                            enum dma_data_direction direction,
-                                           u32 ** sg_ptr)
-{
-       u32 sg_flags;
-       u32 *mptr = *sg_ptr;
-       dma_addr_t dma_addr;
-
-       switch (direction) {
-       case DMA_TO_DEVICE:
-               sg_flags = 0xd4000000;
-               break;
-       case DMA_FROM_DEVICE:
-               sg_flags = 0xd0000000;
-               break;
-       default:
-               return 0;
-       }
-
-       dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
-       if (!dma_mapping_error(&c->pdev->dev, dma_addr)) {
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-               if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
-                       *mptr++ = cpu_to_le32(0x7C020002);
-                       *mptr++ = cpu_to_le32(PAGE_SIZE);
-               }
-#endif
-
-               *mptr++ = cpu_to_le32(sg_flags | size);
-               *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-               if ((sizeof(dma_addr_t) > 4) && c->pae_support)
-                       *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
-#endif
-               *sg_ptr = mptr;
-       }
-       return dma_addr;
-};
-
-/**
- *     i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
- *     @c: I2O controller
- *     @sg: SG list to be mapped
- *     @sg_count: number of elements in the SG list
- *     @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- *     @sg_ptr: pointer to the SG list inside the I2O message
- *
- *     This function does all necessary DMA handling and also writes the I2O
- *     SGL elements into the I2O message. For details on DMA handling see also
- *     dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
- *     list if the allocation was successful.
- *
- *     Returns 0 on failure or 1 on success.
- */
-static inline int i2o_dma_map_sg(struct i2o_controller *c,
+                                           u32 ** sg_ptr);
+extern int i2o_dma_map_sg(struct i2o_controller *c,
                                 struct scatterlist *sg, int sg_count,
                                 enum dma_data_direction direction,
-                                u32 ** sg_ptr)
-{
-       u32 sg_flags;
-       u32 *mptr = *sg_ptr;
-
-       switch (direction) {
-       case DMA_TO_DEVICE:
-               sg_flags = 0x14000000;
-               break;
-       case DMA_FROM_DEVICE:
-               sg_flags = 0x10000000;
-               break;
-       default:
-               return 0;
-       }
-
-       sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
-       if (!sg_count)
-               return 0;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-       if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
-               *mptr++ = cpu_to_le32(0x7C020002);
-               *mptr++ = cpu_to_le32(PAGE_SIZE);
-       }
-#endif
-
-       while (sg_count-- > 0) {
-               if (!sg_count)
-                       sg_flags |= 0xC0000000;
-               *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
-               *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-               if ((sizeof(dma_addr_t) > 4) && c->pae_support)
-                       *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
-#endif
-               sg = sg_next(sg);
-       }
-       *sg_ptr = mptr;
-
-       return 1;
-};
-
-/**
- *     i2o_dma_alloc - Allocate DMA memory
- *     @dev: struct device pointer to the PCI device of the I2O controller
- *     @addr: i2o_dma struct which should get the DMA buffer
- *     @len: length of the new DMA memory
- *     @gfp_mask: GFP mask
- *
- *     Allocate a coherent DMA memory and write the pointers into addr.
- *
- *     Returns 0 on success or -ENOMEM on failure.
- */
-static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
-                               size_t len, gfp_t gfp_mask)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       int dma_64 = 0;
-
-       if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
-               dma_64 = 1;
-               if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
-                       return -ENOMEM;
-       }
-
-       addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
-
-       if ((sizeof(dma_addr_t) > 4) && dma_64)
-               if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
-                       printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
-
-       if (!addr->virt)
-               return -ENOMEM;
-
-       memset(addr->virt, 0, len);
-       addr->len = len;
-
-       return 0;
-};
-
-/**
- *     i2o_dma_free - Free DMA memory
- *     @dev: struct device pointer to the PCI device of the I2O controller
- *     @addr: i2o_dma struct which contains the DMA buffer
- *
- *     Free a coherent DMA memory and set virtual address of addr to NULL.
- */
-static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
-{
-       if (addr->virt) {
-               if (addr->phys)
-                       dma_free_coherent(dev, addr->len, addr->virt,
-                                         addr->phys);
-               else
-                       kfree(addr->virt);
-               addr->virt = NULL;
-       }
-};
-
-/**
- *     i2o_dma_realloc - Realloc DMA memory
- *     @dev: struct device pointer to the PCI device of the I2O controller
- *     @addr: pointer to a i2o_dma struct DMA buffer
- *     @len: new length of memory
- *     @gfp_mask: GFP mask
- *
- *     If there was something allocated in the addr, free it first. If len > 0
- *     than try to allocate it and write the addresses back to the addr
- *     structure. If len == 0 set the virtual address to NULL.
- *
- *     Returns the 0 on success or negative error code on failure.
- */
-static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
-                                 size_t len, gfp_t gfp_mask)
-{
-       i2o_dma_free(dev, addr);
-
-       if (len)
-               return i2o_dma_alloc(dev, addr, len, gfp_mask);
-
-       return 0;
-};
-
-/*
- *     i2o_pool_alloc - Allocate an slab cache and mempool
- *     @mempool: pointer to struct i2o_pool to write data into.
- *     @name: name which is used to identify cache
- *     @size: size of each object
- *     @min_nr: minimum number of objects
- *
- *     First allocates a slab cache with name and size. Then allocates a
- *     mempool which uses the slab cache for allocation and freeing.
- *
- *     Returns 0 on success or negative error code on failure.
- */
-static inline int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
-                                size_t size, int min_nr)
-{
-       pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
-       if (!pool->name)
-               goto exit;
-       strcpy(pool->name, name);
-
-       pool->slab =
-           kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL);
-       if (!pool->slab)
-               goto free_name;
-
-       pool->mempool = mempool_create_slab_pool(min_nr, pool->slab);
-       if (!pool->mempool)
-               goto free_slab;
-
-       return 0;
-
-      free_slab:
-       kmem_cache_destroy(pool->slab);
-
-      free_name:
-       kfree(pool->name);
-
-      exit:
-       return -ENOMEM;
-};
-
-/*
- *     i2o_pool_free - Free slab cache and mempool again
- *     @mempool: pointer to struct i2o_pool which should be freed
- *
- *     Note that you have to return all objects to the mempool again before
- *     calling i2o_pool_free().
- */
-static inline void i2o_pool_free(struct i2o_pool *pool)
-{
-       mempool_destroy(pool->mempool);
-       kmem_cache_destroy(pool->slab);
-       kfree(pool->name);
-};
-
+                                u32 ** sg_ptr);
+extern int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len);
+extern void i2o_dma_free(struct device *dev, struct i2o_dma *addr);
+extern int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
+                                                               size_t len);
+extern int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
+                                size_t size, int min_nr);
+extern void i2o_pool_free(struct i2o_pool *pool);
 /* I2O driver (OSM) functions */
 extern int i2o_driver_register(struct i2o_driver *);
 extern void i2o_driver_unregister(struct i2o_driver *);
index 03067443198a3baf0e5bef0c3ba0dfa05499fd1d..a93a8dd33118f5fe900e2e6a2e79672bdb1f1319 100644 (file)
@@ -40,16 +40,18 @@ struct icmp6hdr {
                 struct icmpv6_nd_ra {
                        __u8            hop_limit;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-                       __u8            reserved:4,
+                       __u8            reserved:3,
                                        router_pref:2,
+                                       home_agent:1,
                                        other:1,
                                        managed:1;
 
 #elif defined(__BIG_ENDIAN_BITFIELD)
                        __u8            managed:1,
                                        other:1,
+                                       home_agent:1,
                                        router_pref:2,
-                                       reserved:4;
+                                       reserved:3;
 #else
 #error "Please fix <asm/byteorder.h>"
 #endif
index 93538b696e3d99f2bb30d96b83d3516c66442233..ad63824460e34d2838d0a77833f21121814251cd 100644 (file)
@@ -233,9 +233,6 @@ struct obs_kernel_param {
                __attribute__((aligned((sizeof(long)))))        \
                = { __setup_str_##unique_id, fn, early }
 
-#define __setup_null_param(str, unique_id)                     \
-       __setup_param(str, unique_id, NULL, 0)
-
 #define __setup(str, fn)                                       \
        __setup_param(str, fn, fn, 0)
 
@@ -296,7 +293,6 @@ void __init parse_early_param(void);
        void cleanup_module(void) __attribute__((alias(#exitfn)));
 
 #define __setup_param(str, unique_id, fn)      /* nothing */
-#define __setup_null_param(str, unique_id)     /* nothing */
 #define __setup(str, func)                     /* nothing */
 #endif
 
index a5802c9c81a47831996a93cffc00fcb7190d4089..b86fb5581ce602f5978ff2a06ddc05eb67f19a07 100644 (file)
@@ -577,9 +577,22 @@ struct input_absinfo {
 #define KEY_BRL_DOT9           0x1f9
 #define KEY_BRL_DOT10          0x1fa
 
+#define KEY_NUMERIC_0          0x200   /* used by phones, remote controls, */
+#define KEY_NUMERIC_1          0x201   /* and other keypads */
+#define KEY_NUMERIC_2          0x202
+#define KEY_NUMERIC_3          0x203
+#define KEY_NUMERIC_4          0x204
+#define KEY_NUMERIC_5          0x205
+#define KEY_NUMERIC_6          0x206
+#define KEY_NUMERIC_7          0x207
+#define KEY_NUMERIC_8          0x208
+#define KEY_NUMERIC_9          0x209
+#define KEY_NUMERIC_STAR       0x20a
+#define KEY_NUMERIC_POUND      0x20b
+
 /* We avoid low common keys in module aliases so they don't get huge. */
 #define KEY_MIN_INTERESTING    KEY_MUTE
-#define KEY_MAX                        0x1ff
+#define KEY_MAX                        0x2ff
 #define KEY_CNT                        (KEY_MAX+1)
 
 /*
index a6d0586e2bf76227488045e7e38267a3f69bc455..3b068e5b56710222f43bd86a3a5f849128526171 100644 (file)
@@ -23,4 +23,7 @@ extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size,
 extern void iommu_area_free(unsigned long *map, unsigned long start,
                            unsigned int nr);
 
+extern unsigned long iommu_num_pages(unsigned long addr, unsigned long len,
+                                    unsigned long io_page_size);
+
 #endif
index e38b6aa2d40c22ec1b04d932b417b805f5fa93ef..041e95aac2bf317c40a3c68a45e223b322c80a26 100644 (file)
@@ -34,7 +34,8 @@ struct resource_list {
  */
 #define IORESOURCE_BITS                0x000000ff      /* Bus-specific bits */
 
-#define IORESOURCE_IO          0x00000100      /* Resource type */
+#define IORESOURCE_TYPE_BITS   0x00000f00      /* Resource type */
+#define IORESOURCE_IO          0x00000100
 #define IORESOURCE_MEM         0x00000200
 #define IORESOURCE_IRQ         0x00000400
 #define IORESOURCE_DMA         0x00000800
@@ -126,6 +127,10 @@ static inline resource_size_t resource_size(struct resource *res)
 {
        return res->end - res->start + 1;
 }
+static inline unsigned long resource_type(struct resource *res)
+{
+       return res->flags & IORESOURCE_TYPE_BITS;
+}
 
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name)   __request_region(&ioport_resource, (start), (n), (name))
index 07a9b52a265418cb4b213ae8b1fff8e6eefbdd9d..7ebbcb1c9ba4e5d6a5a72290c002f37c09617fce 100644 (file)
@@ -61,7 +61,7 @@ extern u8 journal_enable_debug;
        do {                                                            \
                if ((n) <= journal_enable_debug) {                      \
                        printk (KERN_DEBUG "(%s, %d): %s: ",            \
-                               __FILE__, __LINE__, __FUNCTION__);      \
+                               __FILE__, __LINE__, __func__);  \
                        printk (f, ## a);                               \
                }                                                       \
        } while (0)
@@ -984,7 +984,7 @@ extern int  cleanup_journal_tail(journal_t *);
 
 #define jbd_ENOSYS() \
 do {                                                                      \
-       printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \
+       printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
        current->state = TASK_UNINTERRUPTIBLE;                             \
        schedule();                                                        \
 } while (1)
index d2e91ea998fd44b945cb8337cbc0934967b774f9..463d6f10b64f7ffaea2f4fc13e57bc2ca4a95c8e 100644 (file)
@@ -61,7 +61,7 @@ extern u8 jbd2_journal_enable_debug;
        do {                                                            \
                if ((n) <= jbd2_journal_enable_debug) {                 \
                        printk (KERN_DEBUG "(%s, %d): %s: ",            \
-                               __FILE__, __LINE__, __FUNCTION__);      \
+                               __FILE__, __LINE__, __func__);  \
                        printk (f, ## a);                               \
                }                                                       \
        } while (0)
@@ -1143,7 +1143,7 @@ extern int        jbd2_cleanup_journal_tail(journal_t *);
 
 #define jbd_ENOSYS() \
 do {                                                                      \
-       printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \
+       printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
        current->state = TASK_UNINTERRUPTIBLE;                             \
        schedule();                                                        \
 } while (1)
index 8a62d1e84b9b403668000032cd30ab448cced7fb..bb70ebb6a2d5bd9f7435387bb2eb4fa91cbce166 100644 (file)
@@ -3,7 +3,7 @@
  *
  * buffer_head fields for JBD
  *
- * 27 May 2001 Andrew Morton <akpm@digeo.com>
+ * 27 May 2001 Andrew Morton
  *     Created - pulled out of fs.h
  */
 
index b96144887444a222621a4167f646859528887bb5..f3fe34391d8e2664f2d1bef0140b184f879b8e32 100644 (file)
@@ -93,12 +93,10 @@ static inline void print_symbol(const char *fmt, unsigned long addr)
 }
 
 /*
- * Pretty-print a function pointer.
- *
- * ia64 and ppc64 function pointers are really function descriptors,
- * which contain a pointer the real address.
+ * Pretty-print a function pointer.  This function is deprecated.
+ * Please use the "%pF" vsprintf format instead.
  */
-static inline void print_fn_descriptor_symbol(const char *fmt, void *addr)
+static inline void __deprecated print_fn_descriptor_symbol(const char *fmt, void *addr)
 {
 #if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
        addr = *(void **)addr;
index 9687491c483f08b32ae8f9f1f2dd803e9d806fc4..6803318fa2ea80cfa15caeaa3684eda5e41bc942 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/log2.h>
 #include <linux/typecheck.h>
 #include <linux/ratelimit.h>
+#include <linux/dynamic_printk.h>
 #include <asm/byteorder.h>
 #include <asm/bug.h>
 
@@ -238,9 +239,10 @@ extern int oops_in_progress;               /* If set, an oops, panic(), BUG() or die() is in
 extern int panic_timeout;
 extern int panic_on_oops;
 extern int panic_on_unrecovered_nmi;
-extern int tainted;
 extern const char *print_tainted(void);
-extern void add_taint(unsigned);
+extern void add_taint(unsigned flag);
+extern int test_taint(unsigned flag);
+extern unsigned long get_taint(void);
 extern int root_mountflags;
 
 /* Values used for system_state */
@@ -253,16 +255,16 @@ extern enum system_states {
        SYSTEM_SUSPEND_DISK,
 } system_state;
 
-#define TAINT_PROPRIETARY_MODULE       (1<<0)
-#define TAINT_FORCED_MODULE            (1<<1)
-#define TAINT_UNSAFE_SMP               (1<<2)
-#define TAINT_FORCED_RMMOD             (1<<3)
-#define TAINT_MACHINE_CHECK            (1<<4)
-#define TAINT_BAD_PAGE                 (1<<5)
-#define TAINT_USER                     (1<<6)
-#define TAINT_DIE                      (1<<7)
-#define TAINT_OVERRIDDEN_ACPI_TABLE    (1<<8)
-#define TAINT_WARN                     (1<<9)
+#define TAINT_PROPRIETARY_MODULE       0
+#define TAINT_FORCED_MODULE            1
+#define TAINT_UNSAFE_SMP               2
+#define TAINT_FORCED_RMMOD             3
+#define TAINT_MACHINE_CHECK            4
+#define TAINT_BAD_PAGE                 5
+#define TAINT_USER                     6
+#define TAINT_DIE                      7
+#define TAINT_OVERRIDDEN_ACPI_TABLE    8
+#define TAINT_WARN                     9
 
 extern void dump_stack(void) __cold;
 
@@ -306,8 +308,12 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
 #define pr_info(fmt, arg...) \
        printk(KERN_INFO fmt, ##arg)
 
-#ifdef DEBUG
 /* If you are writing a driver, please use dev_dbg instead */
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#define pr_debug(fmt, ...) do { \
+       dynamic_pr_debug(fmt, ##__VA_ARGS__); \
+       } while (0)
+#elif defined(DEBUG)
 #define pr_debug(fmt, arg...) \
        printk(KERN_DEBUG fmt, ##arg)
 #else
index a1a91577813c6bfb25ea89c9304f0c2128a87464..92213a9194e15753b91a21170cb641e97d82513d 100644 (file)
@@ -99,4 +99,7 @@ struct file;
 extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
                                    struct file **filp);
 
+extern int usermodehelper_disable(void);
+extern void usermodehelper_enable(void);
+
 #endif /* __LINUX_KMOD_H__ */
similarity index 98%
rename from drivers/input/misc/map_to_7segment.h
rename to include/linux/map_to_7segment.h
index a424094d9fe21b836b5b13216147ac09fb690811..7df8432c4402b576b9f1d5b116aea47a6182daef 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * drivers/usb/input/map_to_7segment.h
- *
  * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
@@ -36,7 +34,7 @@
  * Usage:
  *
  *   Register a map variable, and fill it with a character set:
- *     static SEG7_DEFAULT_MAP(map_seg7);
+ *     static SEG7_DEFAULT_MAP(map_seg7);
  *
  *
  *   Then use for conversion:
index ec612e66391c62d66dbf26c39e9e2378ccc57a2b..516d955ab8a1bb9e63120a3bb79c0f0d4e08e297 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef MFD_TMIO_H
 #define MFD_TMIO_H
 
+#include <linux/fb.h>
+
 #define tmio_ioread8(addr) readb(addr)
 #define tmio_ioread16(addr) readw(addr)
 #define tmio_ioread16_rep(r, b, l) readsw(r, b, l)
@@ -25,4 +27,21 @@ struct tmio_nand_data {
        unsigned int            num_partitions;
 };
 
+#define FBIO_TMIO_ACC_WRITE    0x7C639300
+#define FBIO_TMIO_ACC_SYNC     0x7C639301
+
+struct tmio_fb_data {
+       int                     (*lcd_set_power)(struct platform_device *fb_dev,
+                                                               bool on);
+       int                     (*lcd_mode)(struct platform_device *fb_dev,
+                                       const struct fb_videomode *mode);
+       int                     num_modes;
+       struct fb_videomode     *modes;
+
+       /* in mm: size of screen */
+       int                     height;
+       int                     width;
+};
+
+
 #endif
index d6a3f47e95cb81251800e85ce9a44d25f4be04ff..eb71b45fdf5af411b42aad9b89ae808c1b19d8e8 100644 (file)
@@ -284,7 +284,7 @@ struct pcmcia_device_id {
 /* Input */
 #define INPUT_DEVICE_ID_EV_MAX         0x1f
 #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING    0x71
-#define INPUT_DEVICE_ID_KEY_MAX                0x1ff
+#define INPUT_DEVICE_ID_KEY_MAX                0x2ff
 #define INPUT_DEVICE_ID_REL_MAX                0x0f
 #define INPUT_DEVICE_ID_ABS_MAX                0x3f
 #define INPUT_DEVICE_ID_MSC_MAX                0x07
index 68e09557c9511ab31da394afd80a58decad3ee71..a41555cbe00ae071a02dab3c88b3c57bf6c38d4b 100644 (file)
@@ -345,7 +345,6 @@ struct module
        /* Reference counts */
        struct module_ref ref[NR_CPUS];
 #endif
-
 };
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
index 30a1d63b6fb5cb37574935ff33c121c6526d111d..cab2a85e2ee82f556cf1515eb14bd6d88ad344b0 100644 (file)
@@ -5,8 +5,6 @@
  *
  * Author:  Marco van Wieringen <mvw@planets.elm.net>
  *
- * Version: $Id: mount.h,v 2.0 1996/11/17 16:48:14 mvw Exp mvw $
- *
  */
 #ifndef _LINUX_MOUNT_H
 #define _LINUX_MOUNT_H
index 0d8424f76899f11d5c96dce8d525c1f54fbe4b1a..7d8e0455ccacb101e79cb9e6a940ccf7f5c41615 100644 (file)
@@ -78,6 +78,9 @@ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
                          int echo);
 extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
 
+extern void nfnl_lock(void);
+extern void nfnl_unlock(void);
+
 #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
        MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
 
index 79886ade070f2e791274c92814bc04bfbcff4947..e2488f5e7cb2bfc4ab275b1a2685bba103713205 100644 (file)
@@ -71,5 +71,8 @@ extern int of_n_size_cells(struct device_node *np);
 extern const struct of_device_id *of_match_node(
        const struct of_device_id *matches, const struct device_node *node);
 extern int of_modalias_node(struct device_node *node, char *modalias, int len);
+extern int of_parse_phandles_with_args(struct device_node *np,
+       const char *list_name, const char *cells_name, int index,
+       struct device_node **out_node, const void **out_args);
 
 #endif /* _LINUX_OF_H */
index 6a0d7cdb577465a84bf5ccf3ef8ff0b86edc4002..e1f83c5065c5e2ad4e4a92f4fa9908939c6f7e0c 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: parport.h,v 1.1 1998/05/17 10:57:52 andrea Exp andrea $ */
-
 /*
  * Any part of this program may be used in documents licensed under
  * the GNU Free Documentation License, Version 1.1 or any later version
index 1176f1f177e298533b80e571a14513ab60c9cfbb..8edddc240e4f61c133308d9af0af7da179b9c56b 100644 (file)
 #define PCI_DEVICE_ID_MATROX_G200_PCI  0x0520
 #define PCI_DEVICE_ID_MATROX_G200_AGP  0x0521
 #define        PCI_DEVICE_ID_MATROX_G400       0x0525
+#define        PCI_DEVICE_ID_MATROX_G200EV_PCI 0x0530
 #define PCI_DEVICE_ID_MATROX_G550      0x2527
 #define PCI_DEVICE_ID_MATROX_VIA       0x4536
 
index 1af82c4e17d4e79a14d1854b35fd39ef93bdb649..d82fe825d62f9571fe6412700d854a326f5d8c4c 100644 (file)
@@ -84,12 +84,6 @@ static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
        return tsk->nsproxy->pid_ns;
 }
 
-static inline struct task_struct *task_child_reaper(struct task_struct *tsk)
-{
-       BUG_ON(tsk != current);
-       return tsk->nsproxy->pid_ns->child_reaper;
-}
-
 void pidhash_init(void);
 void pidmap_init(void);
 
index 95ac21ab3a092369f5f41537614eb9890161d70e..4b8cc6a324797682d08e487d314cb4ce647e2d7c 100644 (file)
@@ -37,6 +37,8 @@ extern int platform_add_devices(struct platform_device **, int);
 
 extern struct platform_device *platform_device_register_simple(const char *, int id,
                                        struct resource *, unsigned int);
+extern struct platform_device *platform_device_register_data(struct device *,
+               const char *, int, const void *, size_t);
 
 extern struct platform_device *platform_device_alloc(const char *name, int id);
 extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
index 4dcce54b6d76f798e11f3e3ae08032ee0fbac592..42de4003c4ee10a52599ea95d7ae9d53964a0bf9 100644 (file)
@@ -419,7 +419,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
 
 #define suspend_report_result(fn, ret)                                 \
        do {                                                            \
-               __suspend_report_result(__FUNCTION__, fn, ret);         \
+               __suspend_report_result(__func__, fn, ret);             \
        } while (0)
 
 #else /* !CONFIG_PM_SLEEP */
index be764e514e35946eeced5615440769912da9e0fa..53b70fd1d9a535d92639a66757646ce5620e21f9 100644 (file)
@@ -22,9 +22,11 @@ struct pnp_dev;
  * Resource Management
  */
 #ifdef CONFIG_PNP
-struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
+struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned long type,
+                               unsigned int num);
 #else
-static inline struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned int type, unsigned int num)
+static inline struct resource *pnp_get_resource(struct pnp_dev *dev,
+                       unsigned long type, unsigned int num)
 {
        return NULL;
 }
index fb61850d1cfcf7b04352c6fa2a9d12c6c91e77f0..27d534f4470d2350cc7cd563e813e5b88ba25c37 100644 (file)
@@ -139,7 +139,6 @@ extern int proc_readdir(struct file *, void *, filldir_t);
 extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
 
 extern const struct file_operations proc_kcore_operations;
-extern const struct file_operations ppc_htab_operations;
 
 extern int pid_ns_prepare_proc(struct pid_namespace *ns);
 extern void pid_ns_release_proc(struct pid_namespace *ns);
index 7e7087239af5fc0497ebf40bf92d65cb99b5749f..570045053ce9bf04bbda46d21a97feb3b76dadb2 100644 (file)
@@ -35,7 +35,9 @@ enum profile_type {
 extern int prof_on __read_mostly;
 
 /* init basic kernel profiler */
-void __init profile_init(void);
+int profile_init(void);
+int profile_setup(char *str);
+int create_proc_profile(void);
 void profile_tick(int type);
 
 /*
@@ -84,9 +86,9 @@ struct pt_regs;
 
 #define prof_on 0
 
-static inline void profile_init(void)
+static inline int profile_init(void)
 {
-       return;
+       return 0;
 }
 
 static inline void profile_tick(int type)
index 376a05048bc580650bd1923c9f21c6e3852cea11..40401b554484ceeafec0ca395097424f99acc2e9 100644 (file)
@@ -28,8 +28,6 @@
  * 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.
- *
- * Version: $Id: quota.h,v 2.0 1996/11/17 16:48:14 mvw Exp mvw $
  */
 
 #ifndef _LINUX_QUOTA_
index ca6b9b5c8d5271b430a534fe59969a09af85c997..a558a4c1d35a2a10eea7d0017fc5326133b8faf4 100644 (file)
@@ -3,9 +3,6 @@
  * macros expand to the right source-code.
  *
  * Author:  Marco van Wieringen <mvw@planets.elm.net>
- *
- * Version: $Id: quotaops.h,v 1.2 1998/01/15 16:22:26 ecd Exp $
- *
  */
 #ifndef _LINUX_QUOTAOPS_
 #define _LINUX_QUOTAOPS_
index 7e375111d0074b390136c56cdca76a1ce6bb5d3c..f38b9c586afbc38c2a3187ac479735b14ad5fffb 100644 (file)
@@ -5,8 +5,8 @@
 
 struct dev_info {
        mdk_rdev_t      *rdev;
-       sector_t        size;
-       sector_t        offset;
+       sector_t        num_sectors;
+       sector_t        start_sector;
 };
 
 typedef struct dev_info dev_info_t;
@@ -15,9 +15,11 @@ struct linear_private_data
 {
        struct linear_private_data *prev;       /* earlier version */
        dev_info_t              **hash_table;
-       sector_t                hash_spacing;
+       sector_t                spacing;
        sector_t                array_sectors;
-       int                     preshift; /* shift before dividing by hash_spacing */
+       int                     sector_shift;   /* shift before dividing
+                                                * by spacing
+                                                */
        dev_info_t              disks[0];
 };
 
index dc0e3fcb9f281b15bc9d0f040ce38a42191a4ea5..82bea14cae1a7a948aafe1a1a1329aa1a9e6037d 100644 (file)
 #define _MD_H
 
 #include <linux/blkdev.h>
-#include <linux/major.h>
-#include <linux/ioctl.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/hdreg.h>
-#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
-#include <linux/delay.h>
-#include <net/checksum.h>
-#include <linux/random.h>
-#include <linux/kernel_stat.h>
-#include <asm/io.h>
-#include <linux/completion.h>
-#include <linux/mempool.h>
-#include <linux/list.h>
-#include <linux/reboot.h>
-#include <linux/vmalloc.h>
-#include <linux/blkpg.h>
-#include <linux/bio.h>
 
 /*
  * 'md_p.h' holds the 'physical' layout of RAID devices
 
 extern int mdp_major;
 
-extern int register_md_personality (struct mdk_personality *p);
-extern int unregister_md_personality (struct mdk_personality *p);
-extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev),
+extern int register_md_personality(struct mdk_personality *p);
+extern int unregister_md_personality(struct mdk_personality *p);
+extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
                                mddev_t *mddev, const char *name);
-extern void md_unregister_thread (mdk_thread_t *thread);
+extern void md_unregister_thread(mdk_thread_t *thread);
 extern void md_wakeup_thread(mdk_thread_t *thread);
 extern void md_check_recovery(mddev_t *mddev);
 extern void md_write_start(mddev_t *mddev, struct bio *bi);
 extern void md_write_end(mddev_t *mddev);
-extern void md_handle_safemode(mddev_t *mddev);
 extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
-extern void md_error (mddev_t *mddev, mdk_rdev_t *rdev);
-extern void md_unplug_mddev(mddev_t *mddev);
+extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
 
 extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
                           sector_t sector, int size, struct page *page);
index e9963af16cda6ade6ede6dded784c2624f4bc449..bc5114d35e99b65db4e11acefe3bae623a7c9db9 100644 (file)
@@ -87,7 +87,7 @@ void reiserfs_warning(struct super_block *s, const char *fmt, ...);
 if( !( cond ) )                                                                \
   reiserfs_panic( NULL, "reiserfs[%i]: assertion " scond " failed at " \
                  __FILE__ ":%i:%s: " format "\n",              \
-                 in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args )
+                 in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __func__ , ##args )
 
 #define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args)
 
index 382bb7951166ec649e7113c4d2eac86194e7ad78..f19b00b7d530a8e60f67e77c5f1c5ac5270e8d9b 100644 (file)
@@ -54,7 +54,7 @@ struct hrtimer_sleeper;
 #ifdef CONFIG_DEBUG_RT_MUTEXES
 # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
        , .name = #mutexname, .file = __FILE__, .line = __LINE__
-# define rt_mutex_init(mutex)                  __rt_mutex_init(mutex, __FUNCTION__)
+# define rt_mutex_init(mutex)                  __rt_mutex_init(mutex, __func__)
  extern void rt_mutex_debug_task_free(struct task_struct *tsk);
 #else
 # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname)
index b4d9fa6f797cdd4653334315664a86a27ec081f1..decf6d8c77b7fa7d3a297653708566bb0bdf9d95 100644 (file)
@@ -11,6 +11,7 @@
 
 struct orion_spi_info {
        u32     tclk;           /* no <linux/clk.h> support yet */
+       u32     enable_clock_fix;
 };
 
 
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
new file mode 100644 (file)
index 0000000..b18ec55
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef __LINUX_SWIOTLB_H
+#define __LINUX_SWIOTLB_H
+
+#include <linux/types.h>
+
+struct device;
+struct dma_attrs;
+struct scatterlist;
+
+extern void
+swiotlb_init(void);
+
+extern void
+*swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+                       dma_addr_t *dma_handle, gfp_t flags);
+
+extern void
+swiotlb_free_coherent(struct device *hwdev, size_t size,
+                     void *vaddr, dma_addr_t dma_handle);
+
+extern dma_addr_t
+swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir);
+
+extern void
+swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
+                    size_t size, int dir);
+
+extern dma_addr_t
+swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size,
+                        int dir, struct dma_attrs *attrs);
+
+extern void
+swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr,
+                          size_t size, int dir, struct dma_attrs *attrs);
+
+extern int
+swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+              int direction);
+
+extern void
+swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+                int direction);
+
+extern int
+swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
+                    int dir, struct dma_attrs *attrs);
+
+extern void
+swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
+                      int nelems, int dir, struct dma_attrs *attrs);
+
+extern void
+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+                           size_t size, int dir);
+
+extern void
+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
+                       int nelems, int dir);
+
+extern void
+swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
+                              size_t size, int dir);
+
+extern void
+swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
+                          int nelems, int dir);
+
+extern void
+swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+                                 unsigned long offset, size_t size, int dir);
+
+extern void
+swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
+                                    unsigned long offset, size_t size,
+                                    int dir);
+
+extern int
+swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr);
+
+extern int
+swiotlb_dma_supported(struct device *hwdev, u64 mask);
+
+#endif /* __LINUX_SWIOTLB_H */
index d0437f36921f803e1bd8be49d1066a7ad1796928..39d471d1163b4e8a54a95f56584f04e8a65a2d61 100644 (file)
@@ -972,7 +972,7 @@ extern int sysctl_perm(struct ctl_table_root *root,
 
 typedef struct ctl_table ctl_table;
 
-typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen,
+typedef int ctl_handler (struct ctl_table *table,
                         void __user *oldval, size_t __user *oldlenp,
                         void __user *newval, size_t newlen);
 
index 37fa24152bd810f7d9dd67b685e738179b5bfdf9..b330e289d71f280f7bb6ca3af431a733039ac420 100644 (file)
@@ -78,6 +78,8 @@ struct sysfs_ops {
        ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
 };
 
+struct sysfs_dirent;
+
 #ifdef CONFIG_SYSFS
 
 int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
@@ -117,9 +119,14 @@ int sysfs_add_file_to_group(struct kobject *kobj,
 void sysfs_remove_file_from_group(struct kobject *kobj,
                        const struct attribute *attr, const char *group);
 
-void sysfs_notify(struct kobject *kobj, char *dir, char *attr);
-
-extern int __must_check sysfs_init(void);
+void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
+void sysfs_notify_dirent(struct sysfs_dirent *sd);
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+                                     const unsigned char *name);
+struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
+void sysfs_put(struct sysfs_dirent *sd);
+void sysfs_printk_last_file(void);
+int __must_check sysfs_init(void);
 
 #else /* CONFIG_SYSFS */
 
@@ -222,7 +229,24 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj,
 {
 }
 
-static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr)
+static inline void sysfs_notify(struct kobject *kobj, const char *dir,
+                               const char *attr)
+{
+}
+static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+}
+static inline
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+                                     const unsigned char *name)
+{
+       return NULL;
+}
+static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+       return NULL;
+}
+static inline void sysfs_put(struct sysfs_dirent *sd)
 {
 }
 
@@ -231,6 +255,10 @@ static inline int __must_check sysfs_init(void)
        return 0;
 }
 
+static inline void sysfs_printk_last_file(void)
+{
+}
+
 #endif /* CONFIG_SYSFS */
 
 #endif /* _SYSFS_H_ */
index 5e88afc9a2fbd5b5e82bc9486087d9f9017cadcd..bdf855c2856fb2905837d72296394e30d6354ad4 100644 (file)
@@ -5,7 +5,7 @@
  * Don't include this header file directly - it is designed to be dragged in via
  * sched.h.
  *
- * Blame akpm@osdl.org for all this.
+ * Blame Andrew Morton for all this.
  */
 
 struct task_io_accounting {
index 0d0cf2a1e7bcfa75cd93bdd8ba355582b14e4619..5b2b6261f193c872631cfeea9c8990e3127d4a8c 100644 (file)
  * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
  * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
- * Version:       $Revision: 4.2 $
- *
- * $Id: telephony.h,v 4.2 2001/08/06 07:09:43 craigs Exp $
- *
  *****************************************************************************/
 
 #ifndef TELEPHONY_H
index e15206a7e82ec9278b25fc062585302f9ed71687..51e883df0fa51fe598832747477533fc4303e30a 100644 (file)
@@ -29,6 +29,8 @@ struct timezone {
 
 #ifdef __KERNEL__
 
+extern struct timezone sys_tz;
+
 /* Parameters used to convert the timespec values: */
 #define MSEC_PER_SEC   1000L
 #define USEC_PER_MSEC  1000L
index 0081147a9fe8cf23578a40bc6392cd8961e98b90..ef609f842faca33c6e9dded2db7bbd09d7adc8d1 100644 (file)
@@ -108,15 +108,6 @@ static inline int waitqueue_active(wait_queue_head_t *q)
        return !list_empty(&q->task_list);
 }
 
-/*
- * Used to distinguish between sync and async io wait context:
- * sync i/o typically specifies a NULL wait queue entry or a wait
- * queue entry bound to a task (current task) to wake up.
- * aio specifies a wait queue entry with an async notification
- * callback routine, not associated with any task.
- */
-#define is_sync_wait(wait)     (!(wait) || ((wait)->private))
-
 extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
 extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
 extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
index e193fb08fd553eb41f782e244b7982e1075c5159..4f26ecc1411b836bcf30dd26320e2304395d7044 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef __MATH_EMU_OP_2_H__
 #define __MATH_EMU_OP_2_H__
 
-#define _FP_FRAC_DECL_2(X)     _FP_W_TYPE X##_f0, X##_f1
+#define _FP_FRAC_DECL_2(X)     _FP_W_TYPE X##_f0 = 0, X##_f1 = 0
 #define _FP_FRAC_COPY_2(D,S)   (D##_f0 = S##_f0, D##_f1 = S##_f1)
 #define _FP_FRAC_SET_2(X,I)    __FP_FRAC_SET_2(X, I)
 #define _FP_FRAC_HIGH_2(X)     (X##_f1)
index bb46e7645d537234bdc44221bccfa8e0e332e4c5..cc1ec396f8d61bcc6e82e851845184011d467eb6 100644 (file)
@@ -73,7 +73,7 @@ do {                                                                  \
        X##_c = FP_CLS_NAN;                                             \
        /* Check for signaling NaN */                                   \
        if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))            \
-         FP_SET_EXCEPTION(FP_EX_INVALID);                              \
+         FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_SNAN);         \
       }                                                                        \
     break;                                                             \
   }                                                                    \
@@ -324,7 +324,7 @@ do {                                                                             \
        _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                              \
        R##_s = _FP_NANSIGN_##fs;                                            \
        R##_c = FP_CLS_NAN;                                                  \
-       FP_SET_EXCEPTION(FP_EX_INVALID);                                     \
+       FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI);                 \
        break;                                                               \
       }                                                                             \
     /* FALLTHRU */                                                          \
@@ -431,7 +431,7 @@ do {                                                        \
     R##_s = _FP_NANSIGN_##fs;                          \
     R##_c = FP_CLS_NAN;                                        \
     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
-    FP_SET_EXCEPTION(FP_EX_INVALID);                   \
+    FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IMZ);\
     break;                                             \
                                                        \
   default:                                             \
@@ -490,11 +490,15 @@ do {                                                      \
     break;                                             \
                                                        \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):         \
+    R##_s = _FP_NANSIGN_##fs;                          \
+    R##_c = FP_CLS_NAN;                                        \
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
+    FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IDI);\
   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):       \
     R##_s = _FP_NANSIGN_##fs;                          \
     R##_c = FP_CLS_NAN;                                        \
     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
-    FP_SET_EXCEPTION(FP_EX_INVALID);                   \
+    FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ZDZ);\
     break;                                             \
                                                        \
   default:                                             \
index a6f873b45f98aa04466fcea158c13711157b0edb..3f284bc031809f6cef05a36360f2c54ca2879ad9 100644 (file)
 #ifndef FP_EX_INVALID
 #define FP_EX_INVALID          0
 #endif
+#ifndef FP_EX_INVALID_SNAN
+#define FP_EX_INVALID_SNAN     0
+#endif
+/* inf - inf */
+#ifndef FP_EX_INVALID_ISI
+#define FP_EX_INVALID_ISI      0
+#endif
+/* inf / inf */
+#ifndef FP_EX_INVALID_IDI
+#define FP_EX_INVALID_IDI      0
+#endif
+/* 0 / 0 */
+#ifndef FP_EX_INVALID_ZDZ
+#define FP_EX_INVALID_ZDZ      0
+#endif
+/* inf * 0 */
+#ifndef FP_EX_INVALID_IMZ
+#define FP_EX_INVALID_IMZ      0
+#endif
 #ifndef FP_EX_OVERFLOW
 #define FP_EX_OVERFLOW         0
 #endif
index 64a2ec746a3e151779ca9ee00aac3db6cd4ca7da..c5a6e22a4b37d626d90370b3becb212105534478 100644 (file)
@@ -24,7 +24,7 @@
 
 extern unsigned int saa7146_debug;
 
-//#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),KBUILD_MODNAME,__FUNCTION__)
+//#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),KBUILD_MODNAME,__func__)
 
 #ifndef DEBUG_VARIABLE
        #define DEBUG_VARIABLE saa7146_debug
index c3626c0ba9d39a4358e028c328dfe534c5393b18..fb163e2e0de60c2c9df90b0980c4f84aadf6b9a1 100644 (file)
@@ -61,7 +61,7 @@ extern unsigned int p9_debug_level;
 do {  \
        if ((p9_debug_level & level) == level) \
                printk(KERN_NOTICE "-- %s (%d): " \
-               format , __FUNCTION__, task_pid_nr(current) , ## arg); \
+               format , __func__, task_pid_nr(current) , ## arg); \
 } while (0)
 
 #define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR,   \
@@ -76,7 +76,7 @@ do {  \
 #define P9_EPRINTK(level, format, arg...) \
 do { \
        printk(level "9p: %s (%d): " \
-               format , __FUNCTION__, task_pid_nr(current), ## arg); \
+               format , __func__, task_pid_nr(current), ## arg); \
 } while (0)
 
 /**
index 6f8418bf42417c218b112a4ae46b5b942c7863ee..996d12df75940f1ac722b52d764e5cd6c6d9a4c5 100644 (file)
@@ -54,8 +54,8 @@
 #define SOL_RFCOMM     18
 
 #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
-#define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
-#define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __FUNCTION__ , ## arg)
+#define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
+#define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __func__ , ## arg)
 
 /* Connection and socket states */
 enum {
index 6048579d0b2433edf27132f086cfcc7509dd752d..93a56de3594be63de5c2a2847ea78fbb68db940b 100644 (file)
@@ -114,7 +114,7 @@ extern u32 ieee80211_debug_level;
 #define IEEE80211_DEBUG(level, fmt, args...) \
 do { if (ieee80211_debug_level & (level)) \
   printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
-         in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
 static inline bool ieee80211_ratelimit_debug(u32 level)
 {
        return (ieee80211_debug_level & level) && net_ratelimit();
index 1cbccaf0de3f30f161b01965e0b70331490cb1da..bc026ecb513f7c57f1d836017f4a02b6d8e72a57 100644 (file)
@@ -396,7 +396,7 @@ extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
 int ipv4_doint_and_flush(ctl_table *ctl, int write,
                         struct file* filp, void __user *buffer,
                         size_t *lenp, loff_t *ppos);
-int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
+int ipv4_doint_and_flush_strategy(ctl_table *table,
                                  void __user *oldval, size_t __user *oldlenp,
                                  void __user *newval, size_t newlen);
 #ifdef CONFIG_PROC_FS
index 0b2071d9326de8c059ed814848247c50d24535cb..fe9fcf73c85ed26135b802a959382a85e5d64e43 100644 (file)
@@ -165,13 +165,13 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
     do {                                                               \
            if (level <= ip_vs_get_debug_level())                       \
                    printk(KERN_DEBUG "Enter: %s, %s line %i\n",        \
-                          __FUNCTION__, __FILE__, __LINE__);           \
+                          __func__, __FILE__, __LINE__);               \
     } while (0)
 #define LeaveFunction(level)                                            \
     do {                                                                \
            if (level <= ip_vs_get_debug_level())                       \
                        printk(KERN_DEBUG "Leave: %s, %s line %i\n",    \
-                              __FUNCTION__, __FILE__, __LINE__);       \
+                              __func__, __FILE__, __LINE__);       \
     } while (0)
 #else
 #define EnterFunction(level)   do {} while (0)
index 08387553b57e5ee18aeb9f3c8890cdd3d5f54a20..7e582061b230dd9dce935059d959572cbba7cc9a 100644 (file)
@@ -72,7 +72,7 @@ do {  if (irda_debug >= (n)) \
 #define IRDA_ASSERT(expr, func) \
 do { if(!(expr)) { \
        printk( "Assertion failed! %s:%s:%d %s\n", \
-               __FILE__,__FUNCTION__,__LINE__,(#expr) ); \
+               __FILE__,__func__,__LINE__,(#expr) ); \
        func } } while (0)
 #define IRDA_ASSERT_LABEL(label)       label
 #else
index 5617a1613c917b84c43758fd30400fd816b1a618..d861197f83c76aefdd1ec6dd1854057c6b27f177 100644 (file)
@@ -645,7 +645,8 @@ enum ieee80211_key_flags {
  *     - Temporal Encryption Key (128 bits)
  *     - Temporal Authenticator Tx MIC Key (64 bits)
  *     - Temporal Authenticator Rx MIC Key (64 bits)
- *
+ * @icv_len: FIXME
+ * @iv_len: FIXME
  */
 struct ieee80211_key_conf {
        enum ieee80211_key_alg alg;
index a01b7c4dc76371dba52e2aebac23ae254238b6e5..11dd0137c6a5b34ee1434c4b699b68d304ce5d46 100644 (file)
@@ -129,9 +129,8 @@ extern int                  ndisc_ifinfo_sysctl_change(struct ctl_table *ctl,
                                                           void __user *buffer,
                                                           size_t *lenp,
                                                           loff_t *ppos);
-int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
-                                int nlen, void __user *oldval,
-                                size_t __user *oldlenp,
+int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl,
+                                void __user *oldval, size_t __user *oldlenp,
                                 void __user *newval, size_t newlen);
 #endif
 
index f29eeb9777e0d8282c174c1f00c9a4e9423ce55e..58684066388c45750e1f5a21199ccc8a2557670b 100644 (file)
@@ -25,4 +25,12 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
        else
                return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
 }
+
+struct nlattr;
+
+extern int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+                                 enum nf_nat_manip_type manip,
+                                 struct nlattr *attr);
+
 #endif /* _NF_NAT_CORE_H */
index 703305d00365ff86460315c5490b3417b36ce2f1..ed71b110edf795094336e436816d9bdd5e6a1aab 100644 (file)
@@ -303,7 +303,7 @@ extern int sctp_debug_flag;
 #define SCTP_ASSERT(expr, str, func) \
        if (!(expr)) { \
                SCTP_DEBUG_PRINTK("Assertion Failed: %s(%s) at %s:%s:%d\n", \
-                       str, (#expr), __FILE__, __FUNCTION__, __LINE__); \
+                       str, (#expr), __FILE__, __func__, __LINE__); \
                func; \
        }
 
index 717440575380e3a0af91b230eac8f33bad15893a..d3c1d4e2c8e3a7f1f62d60d3d678e270fd374567 100644 (file)
@@ -4,7 +4,7 @@
 #endif
 
 #if CYBLAFB_DEBUG
-#define debug(f,a...)  printk("%s:" f,  __FUNCTION__ , ## a);
+#define debug(f,a...)  printk("%s:" f,  __func__ , ## a);
 #else
 #define debug(f,a...)
 #endif
index 38910da0ae59f083c27312674413c73e4a32034b..08b663782956a3aa3f295acc17c7bf581173ca83 100644 (file)
@@ -123,7 +123,6 @@ typedef volatile struct {
 
 struct neofb_par {
        struct vgastate state;
-       struct mutex open_lock;
        unsigned int ref_count;
 
        unsigned char MiscOutReg;       /* Misc */
index 099ffa5e5bee9b75195850977b5b6e4ef2240014..d5dcaf154ba4092412cb45e59bebebe5c6d23c5f 100644 (file)
 #define SC_BOTTOM_RIGHT                        0x16F0  
 #define SRC_SC_BOTTOM_RIGHT                    0x16F4  
 #define RB2D_DSTCACHE_MODE                    0x3428
-#define RB2D_DSTCACHE_CTLSTAT                 0x342C
+#define RB2D_DSTCACHE_CTLSTAT_broken          0x342C /* do not use */
 #define LVDS_GEN_CNTL                         0x02d0
 #define LVDS_PLL_CNTL                         0x02d4
 #define FP2_GEN_CNTL                           0x0288
 #define CRTC_DISPLAY_DIS                          (1 << 10)
 #define CRTC_CRT_ON                               (1 << 15)
 
+/* DSTCACHE_MODE bits constants */
+#define RB2D_DC_AUTOFLUSH_ENABLE                   (1 << 8)
+#define RB2D_DC_DC_DISABLE_IGNORE_PE               (1 << 17)
 
 /* DSTCACHE_CTLSTAT bit constants */
 #define RB2D_DC_FLUSH_2D                          (1 << 0)
 #define RB2D_DC_FLUSH_ALL                         (RB2D_DC_FLUSH_2D | RB2D_DC_FREE_2D)
 #define RB2D_DC_BUSY                              (1 << 31)
 
+/* DSTCACHE_MODE bits constants */
+#define RB2D_DC_AUTOFLUSH_ENABLE                   (1 << 8)
+#define RB2D_DC_DC_DISABLE_IGNORE_PE               (1 << 17)
 
 /* CRTC_GEN_CNTL bit constants */
 #define CRTC_DBL_SCAN_EN                           0x00000001
 #define GMC_DST_16BPP_YVYU422                      0x00000c00
 #define GMC_DST_32BPP_AYUV444                      0x00000e00
 #define GMC_DST_16BPP_ARGB4444                     0x00000f00
-#define GMC_SRC_MONO                               0x00000000
-#define GMC_SRC_MONO_LBKGD                         0x00001000
-#define GMC_SRC_DSTCOLOR                           0x00003000
 #define GMC_BYTE_ORDER_MSB_TO_LSB                  0x00000000
 #define GMC_BYTE_ORDER_LSB_TO_MSB                  0x00004000
 #define GMC_DP_CONVERSION_TEMP_9300                0x00008000
 #define GMC_DP_CONVERSION_TEMP_6500                0x00000000
-#define GMC_DP_SRC_RECT                            0x02000000
-#define GMC_DP_SRC_HOST                            0x03000000
 #define GMC_DP_SRC_HOST_BYTEALIGN                  0x04000000
 #define GMC_3D_FCN_EN_CLR                          0x00000000
 #define GMC_3D_FCN_EN_SET                          0x08000000
 #define GMC_WRITE_MASK_LEAVE                       0x00000000
 #define GMC_WRITE_MASK_SET                         0x40000000
 #define GMC_CLR_CMP_CNTL_DIS                      (1 << 28)
+#define GMC_SRC_DATATYPE_MASK                     (3 << 12)
+#define GMC_SRC_DATATYPE_MONO_FG_BG               (0 << 12)
+#define GMC_SRC_DATATYPE_MONO_FG_LA               (1 << 12)
 #define GMC_SRC_DATATYPE_COLOR                    (3 << 12)
 #define ROP3_S                                    0x00cc0000
 #define ROP3_SRCCOPY                              0x00cc0000
 #define DP_SRC_SOURCE_MASK                        (7    << 24)
 #define GMC_BRUSH_NONE                            (15   <<  4)
 #define DP_SRC_SOURCE_MEMORY                      (2    << 24)
+#define DP_SRC_SOURCE_HOST_DATA                           (3    << 24)
 #define GMC_BRUSH_SOLIDCOLOR                      0x000000d0
 
 /* DP_MIX bit constants */
 #define DISP_PWR_MAN_TV_ENABLE_RST                 (1 << 25)
 #define DISP_PWR_MAN_AUTO_PWRUP_EN                 (1 << 26)
 
+/* RBBM_GUICNTL constants */
+#define RBBM_GUICNTL_HOST_DATA_SWAP_NONE          (0 << 0)
+#define RBBM_GUICNTL_HOST_DATA_SWAP_16BIT          (1 << 0)
+#define RBBM_GUICNTL_HOST_DATA_SWAP_32BIT         (2 << 0)
+#define RBBM_GUICNTL_HOST_DATA_SWAP_HDW                   (3 << 0)
+
 /* masks */
 
 #define CONFIG_MEMSIZE_MASK            0x1f000000
index c99d261df8f72adbb034fec1970ee5ff2b2c9ded..fe41b84079460033618a0598fa424aefc6c55576 100644 (file)
@@ -14,7 +14,8 @@
 #define        S1D13XXXFB_H
 
 #define S1D_PALETTE_SIZE               256
-#define S1D_CHIP_REV                   7       /* expected chip revision number for s1d13806 */
+#define S1D13506_CHIP_REV              4       /* expected chip revision number for s1d13506 */
+#define S1D13806_CHIP_REV              7       /* expected chip revision number for s1d13806 */
 #define S1D_FBID                       "S1D13806"
 #define S1D_DEVICENAME                 "s1d13806fb"
 
index 8a8e2d00c40e1f73a6dafe6c114057014ec15138..5ceff3249a2d84cd23110b99fb3f8a076e8cf56c 100644 (file)
@@ -713,6 +713,14 @@ config SHMEM
          option replaces shmem and tmpfs with the much simpler ramfs code,
          which may be appropriate on small systems without swap.
 
+config AIO
+       bool "Enable AIO support" if EMBEDDED
+       default y
+       help
+         This option enables POSIX asynchronous I/O which may by used
+          by some high performance threaded applications. Disabling
+          this option saves about 7k.
+
 config VM_EVENT_COUNTERS
        default y
        bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
index 48b3fadd83ed90f846555079d02e87e9d708af0c..4c87ee1fe5d30fe1783f0800fde7e3888aad298e 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <linux/raid/md.h>
+#include <linux/delay.h>
 
 #include "do_mounts.h"
 
index fedef93b586fad4146bf1f1cfd04dffbb012c0e1..a7c748fa977a44c2887ad9fcaee3beddf8d4f45e 100644 (file)
@@ -71,7 +71,7 @@ identify_ramdisk_image(int fd, int start_block)
        sys_read(fd, buf, size);
 
        /*
-        * If it matches the gzip magic numbers, return -1
+        * If it matches the gzip magic numbers, return 0
         */
        if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
                printk(KERN_NOTICE
index 644fc01ad5f05244f3f3012becffda2326b2b65d..4f5ba75aaa7c67d1d80754e6b0be67f68151dfda 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/syscalls.h>
+#include <linux/utime.h>
 
 static __initdata char *message;
 static void __init error(char *x)
@@ -72,6 +73,49 @@ static void __init free_hash(void)
        }
 }
 
+static long __init do_utime(char __user *filename, time_t mtime)
+{
+       struct timespec t[2];
+
+       t[0].tv_sec = mtime;
+       t[0].tv_nsec = 0;
+       t[1].tv_sec = mtime;
+       t[1].tv_nsec = 0;
+
+       return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW);
+}
+
+static __initdata LIST_HEAD(dir_list);
+struct dir_entry {
+       struct list_head list;
+       char *name;
+       time_t mtime;
+};
+
+static void __init dir_add(const char *name, time_t mtime)
+{
+       struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL);
+       if (!de)
+               panic("can't allocate dir_entry buffer");
+       INIT_LIST_HEAD(&de->list);
+       de->name = kstrdup(name, GFP_KERNEL);
+       de->mtime = mtime;
+       list_add(&de->list, &dir_list);
+}
+
+static void __init dir_utime(void)
+{
+       struct dir_entry *de, *tmp;
+       list_for_each_entry_safe(de, tmp, &dir_list, list) {
+               list_del(&de->list);
+               do_utime(de->name, de->mtime);
+               kfree(de->name);
+               kfree(de);
+       }
+}
+
+static __initdata time_t mtime;
+
 /* cpio header parsing */
 
 static __initdata unsigned long ino, major, minor, nlink;
@@ -97,6 +141,7 @@ static void __init parse_header(char *s)
        uid = parsed[2];
        gid = parsed[3];
        nlink = parsed[4];
+       mtime = parsed[5];
        body_len = parsed[6];
        major = parsed[7];
        minor = parsed[8];
@@ -130,6 +175,7 @@ static inline void __init eat(unsigned n)
        count -= n;
 }
 
+static __initdata char *vcollected;
 static __initdata char *collected;
 static __initdata int remains;
 static __initdata char *collect;
@@ -271,6 +317,7 @@ static int __init do_name(void)
                        if (wfd >= 0) {
                                sys_fchown(wfd, uid, gid);
                                sys_fchmod(wfd, mode);
+                               vcollected = kstrdup(collected, GFP_KERNEL);
                                state = CopyFile;
                        }
                }
@@ -278,12 +325,14 @@ static int __init do_name(void)
                sys_mkdir(collected, mode);
                sys_chown(collected, uid, gid);
                sys_chmod(collected, mode);
+               dir_add(collected, mtime);
        } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
                   S_ISFIFO(mode) || S_ISSOCK(mode)) {
                if (maybe_link() == 0) {
                        sys_mknod(collected, mode, rdev);
                        sys_chown(collected, uid, gid);
                        sys_chmod(collected, mode);
+                       do_utime(collected, mtime);
                }
        }
        return 0;
@@ -294,6 +343,8 @@ static int __init do_copy(void)
        if (count >= body_len) {
                sys_write(wfd, victim, body_len);
                sys_close(wfd);
+               do_utime(vcollected, mtime);
+               kfree(vcollected);
                eat(body_len);
                state = SkipIt;
                return 0;
@@ -311,6 +362,7 @@ static int __init do_symlink(void)
        clean_path(collected, 0);
        sys_symlink(collected + N_ALIGN(name_len), collected);
        sys_lchown(collected, uid, gid);
+       do_utime(collected, mtime);
        state = SkipIt;
        next_state = Reset;
        return 0;
@@ -466,6 +518,7 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
                buf += inptr;
                len -= inptr;
        }
+       dir_utime();
        kfree(window);
        kfree(name_buf);
        kfree(symlink_buf);
index 69bc85978ba0bb04f0f77745cfa842aea69b7c76..0dfebc5094264fce2c95d62dfc5ff432eee5db58 100644 (file)
@@ -131,7 +131,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
 
 #ifdef CONFIG_SYSCTL_SYSCALL
 /* The generic sysctl ipc data routine. */
-static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
+static int sysctl_ipc_data(ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -169,14 +169,13 @@ static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
        return 1;
 }
 
-static int sysctl_ipc_registered_data(ctl_table *table, int __user *name,
-               int nlen, void __user *oldval, size_t __user *oldlenp,
+static int sysctl_ipc_registered_data(ctl_table *table,
+               void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        int rc;
 
-       rc = sysctl_ipc_data(table, name, nlen, oldval, oldlenp, newval,
-               newlen);
+       rc = sysctl_ipc_data(table, oldval, oldlenp, newval, newlen);
 
        if (newval && newlen && rc > 0)
                /*
index bf1bc36cb7ee62bc95021ba62253d5b667802952..082122469b17490c1d0a1b634055efc079be81c1 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -504,7 +504,7 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
        return semzcnt;
 }
 
-void free_un(struct rcu_head *head)
+static void free_un(struct rcu_head *head)
 {
        struct sem_undo *un = container_of(head, struct sem_undo, rcu);
        kfree(un);
index a0123d75ec9a7624f897bc2984ca4009b61abfbc..8c6e1c17e6d37faae0870c2d9ff5635c1e192037 100644 (file)
@@ -2735,6 +2735,8 @@ void cgroup_fork_callbacks(struct task_struct *child)
  * Called on every change to mm->owner. mm_init_owner() does not
  * invoke this routine, since it assigns the mm->owner the first time
  * and does not change it.
+ *
+ * The callbacks are invoked with mmap_sem held in read mode.
  */
 void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
 {
@@ -2750,7 +2752,7 @@ void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
                        if (oldcgrp == newcgrp)
                                continue;
                        if (ss->mm_owner_changed)
-                               ss->mm_owner_changed(ss, oldcgrp, newcgrp);
+                               ss->mm_owner_changed(ss, oldcgrp, newcgrp, new);
                }
        }
 }
index 32c254a8ab9af07ae3ac102972063956592e0b3b..143990e48cb9aab2af2f04d93a372d63dc570882 100644 (file)
 
 #include <asm/uaccess.h>
 
+/*
+ * Note that the native side is already converted to a timespec, because
+ * that's what we want anyway.
+ */
+static int compat_get_timeval(struct timespec *o,
+               struct compat_timeval __user *i)
+{
+       long usec;
+
+       if (get_user(o->tv_sec, &i->tv_sec) ||
+           get_user(usec, &i->tv_usec))
+               return -EFAULT;
+       o->tv_nsec = usec * 1000;
+       return 0;
+}
+
+static int compat_put_timeval(struct compat_timeval __user *o,
+               struct timeval *i)
+{
+       return (put_user(i->tv_sec, &o->tv_sec) ||
+               put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0;
+}
+
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz)
+{
+       if (tv) {
+               struct timeval ktv;
+               do_gettimeofday(&ktv);
+               if (compat_put_timeval(tv, &ktv))
+                       return -EFAULT;
+       }
+       if (tz) {
+               if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+                       return -EFAULT;
+       }
+
+       return 0;
+}
+
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+               struct timezone __user *tz)
+{
+       struct timespec kts;
+       struct timezone ktz;
+
+       if (tv) {
+               if (compat_get_timeval(&kts, tv))
+                       return -EFAULT;
+       }
+       if (tz) {
+               if (copy_from_user(&ktz, tz, sizeof(ktz)))
+                       return -EFAULT;
+       }
+
+       return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+}
+
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
        return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
index d2c60a82279085e80d0a46edbc0a3557e9b87f83..f903189c530440395417f7b873aff50e9936dc47 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dma.c,v 1.7 1994/12/28 03:35:33 root Exp root $
+/*
  * linux/kernel/dma.c: A DMA channel allocator. Inspired by linux/kernel/irq.c.
  *
  * Written by Hennus Bergman, 1992.
index 85a83c831856c193570e40a3b7d3e03ef8862d1c..0ef4673e351bddd4e738f88941511efa02f062fa 100644 (file)
@@ -640,24 +640,23 @@ retry:
 assign_new_owner:
        BUG_ON(c == p);
        get_task_struct(c);
+       read_unlock(&tasklist_lock);
+       down_write(&mm->mmap_sem);
        /*
         * The task_lock protects c->mm from changing.
         * We always want mm->owner->mm == mm
         */
        task_lock(c);
-       /*
-        * Delay read_unlock() till we have the task_lock()
-        * to ensure that c does not slip away underneath us
-        */
-       read_unlock(&tasklist_lock);
        if (c->mm != mm) {
                task_unlock(c);
+               up_write(&mm->mmap_sem);
                put_task_struct(c);
                goto retry;
        }
        cgroup_mm_owner_callbacks(mm->owner, c);
        mm->owner = c;
        task_unlock(c);
+       up_write(&mm->mmap_sem);
        put_task_struct(c);
 }
 #endif /* CONFIG_MM_OWNER */
index 38fc10ac75415a8ff4da69b68d90facf61eb5e41..5072cf1685a27ca9fc78986e3438ab53baa882a4 100644 (file)
@@ -260,7 +260,6 @@ const char *kallsyms_lookup(unsigned long addr,
        /* see if it's in a module */
        return module_address_lookup(addr, symbolsize, offset, modname,
                                     namebuf);
-       return NULL;
 }
 
 int lookup_symbol_name(unsigned long addr, char *symname)
index 2456d1a0befbd45b91cd7cb7a97ae6d2fb270c4c..3d3c3ea3a023376f2ecf8c16b6c89aed39da67f4 100644 (file)
@@ -113,7 +113,7 @@ int request_module(const char *fmt, ...)
        return ret;
 }
 EXPORT_SYMBOL(request_module);
-#endif /* CONFIG_KMOD */
+#endif /* CONFIG_MODULES */
 
 struct subprocess_info {
        struct work_struct work;
@@ -265,7 +265,7 @@ static void __call_usermodehelper(struct work_struct *work)
        }
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY
  * (used for preventing user land processes from being created after the user
@@ -288,39 +288,37 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq);
  */
 #define RUNNING_HELPERS_TIMEOUT        (5 * HZ)
 
-static int usermodehelper_pm_callback(struct notifier_block *nfb,
-                                       unsigned long action,
-                                       void *ignored)
+/**
+ * usermodehelper_disable - prevent new helpers from being started
+ */
+int usermodehelper_disable(void)
 {
        long retval;
 
-       switch (action) {
-       case PM_HIBERNATION_PREPARE:
-       case PM_SUSPEND_PREPARE:
-               usermodehelper_disabled = 1;
-               smp_mb();
-               /*
-                * From now on call_usermodehelper_exec() won't start any new
-                * helpers, so it is sufficient if running_helpers turns out to
-                * be zero at one point (it may be increased later, but that
-                * doesn't matter).
-                */
-               retval = wait_event_timeout(running_helpers_waitq,
+       usermodehelper_disabled = 1;
+       smp_mb();
+       /*
+        * From now on call_usermodehelper_exec() won't start any new
+        * helpers, so it is sufficient if running_helpers turns out to
+        * be zero at one point (it may be increased later, but that
+        * doesn't matter).
+        */
+       retval = wait_event_timeout(running_helpers_waitq,
                                        atomic_read(&running_helpers) == 0,
                                        RUNNING_HELPERS_TIMEOUT);
-               if (retval) {
-                       return NOTIFY_OK;
-               } else {
-                       usermodehelper_disabled = 0;
-                       return NOTIFY_BAD;
-               }
-       case PM_POST_HIBERNATION:
-       case PM_POST_SUSPEND:
-               usermodehelper_disabled = 0;
-               return NOTIFY_OK;
-       }
+       if (retval)
+               return 0;
 
-       return NOTIFY_DONE;
+       usermodehelper_disabled = 0;
+       return -EAGAIN;
+}
+
+/**
+ * usermodehelper_enable - allow new helpers to be started again
+ */
+void usermodehelper_enable(void)
+{
+       usermodehelper_disabled = 0;
 }
 
 static void helper_lock(void)
@@ -334,18 +332,12 @@ static void helper_unlock(void)
        if (atomic_dec_and_test(&running_helpers))
                wake_up(&running_helpers_waitq);
 }
-
-static void register_pm_notifier_callback(void)
-{
-       pm_notifier(usermodehelper_pm_callback, 0);
-}
-#else /* CONFIG_PM */
+#else /* CONFIG_PM_SLEEP */
 #define usermodehelper_disabled        0
 
 static inline void helper_lock(void) {}
 static inline void helper_unlock(void) {}
-static inline void register_pm_notifier_callback(void) {}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 /**
  * call_usermodehelper_setup - prepare to call a usermode helper
@@ -515,5 +507,4 @@ void __init usermodehelper_init(void)
 {
        khelper_wq = create_singlethread_workqueue("khelper");
        BUG_ON(!khelper_wq);
-       register_pm_notifier_callback();
 }
index 75bc2cd9ebc6a7307aa15c404a914559bcab917b..8b57a2597f21fda9c9602e27028753f1f7325234 100644 (file)
@@ -404,7 +404,7 @@ void kretprobe_hash_lock(struct task_struct *tsk,
        spin_lock_irqsave(hlist_lock, *flags);
 }
 
-void kretprobe_table_lock(unsigned long hash, unsigned long *flags)
+static void kretprobe_table_lock(unsigned long hash, unsigned long *flags)
 {
        spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
        spin_lock_irqsave(hlist_lock, *flags);
index e53bc30e9ba5aa8b55311fd6700191b0f21a9597..08dd8ed86c77a7f7d05316a794f2eaf2f378c058 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
+#include <linux/profile.h>
 #include <linux/sched.h>
 
 #define KERNEL_ATTR_RO(_name) \
@@ -53,6 +54,37 @@ static ssize_t uevent_helper_store(struct kobject *kobj,
 KERNEL_ATTR_RW(uevent_helper);
 #endif
 
+#ifdef CONFIG_PROFILING
+static ssize_t profiling_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", prof_on);
+}
+static ssize_t profiling_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t count)
+{
+       int ret;
+
+       if (prof_on)
+               return -EEXIST;
+       /*
+        * This eventually calls into get_option() which
+        * has a ton of callers and is not const.  It is
+        * easiest to cast it away here.
+        */
+       profile_setup((char *)buf);
+       ret = profile_init();
+       if (ret)
+               return ret;
+       ret = create_proc_profile();
+       if (ret)
+               return ret;
+       return count;
+}
+KERNEL_ATTR_RW(profiling);
+#endif
+
 #ifdef CONFIG_KEXEC
 static ssize_t kexec_loaded_show(struct kobject *kobj,
                                 struct kobj_attribute *attr, char *buf)
@@ -109,6 +141,9 @@ static struct attribute * kernel_attrs[] = {
        &uevent_seqnum_attr.attr,
        &uevent_helper_attr.attr,
 #endif
+#ifdef CONFIG_PROFILING
+       &profiling_attr.attr,
+#endif
 #ifdef CONFIG_KEXEC
        &kexec_loaded_attr.attr,
        &kexec_crash_loaded_attr.attr,
index 9db11911e04b7b55df05fd9f928f5629fe46430d..b7205f67cfaf570aa4aee965cae7e953fec65a2f 100644 (file)
@@ -100,7 +100,7 @@ static inline int strong_try_module_get(struct module *mod)
 static inline void add_taint_module(struct module *mod, unsigned flag)
 {
        add_taint(flag);
-       mod->taints |= flag;
+       mod->taints |= (1U << flag);
 }
 
 /*
@@ -784,6 +784,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
        mutex_lock(&module_mutex);
        /* Store the name of the last unloaded module for diagnostic purposes */
        strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
+       unregister_dynamic_debug_module(mod->name);
        free_module(mod);
 
  out:
@@ -923,7 +924,7 @@ static const char vermagic[] = VERMAGIC_STRING;
 static int try_to_force_load(struct module *mod, const char *symname)
 {
 #ifdef CONFIG_MODULE_FORCE_LOAD
-       if (!(tainted & TAINT_FORCED_MODULE))
+       if (!test_taint(TAINT_FORCED_MODULE))
                printk("%s: no version for \"%s\" found: kernel tainted.\n",
                       mod->name, symname);
        add_taint_module(mod, TAINT_FORCED_MODULE);
@@ -1033,7 +1034,7 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
        const unsigned long *crc;
 
        ret = find_symbol(name, &owner, &crc,
-                         !(mod->taints & TAINT_PROPRIETARY_MODULE), true);
+                         !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
        if (!IS_ERR_VALUE(ret)) {
                /* use_module can fail due to OOM,
                   or module initialization or unloading */
@@ -1173,7 +1174,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
                while (i-- > 0)
                        sysfs_remove_bin_file(notes_attrs->dir,
                                              &notes_attrs->attrs[i]);
-               kobject_del(notes_attrs->dir);
+               kobject_put(notes_attrs->dir);
        }
        kfree(notes_attrs);
 }
@@ -1634,7 +1635,7 @@ static void set_license(struct module *mod, const char *license)
                license = "unspecified";
 
        if (!license_is_gpl_compatible(license)) {
-               if (!(tainted & TAINT_PROPRIETARY_MODULE))
+               if (!test_taint(TAINT_PROPRIETARY_MODULE))
                        printk(KERN_WARNING "%s: module license '%s' taints "
                                "kernel.\n", mod->name, license);
                add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
@@ -1783,6 +1784,33 @@ static inline void add_kallsyms(struct module *mod,
 }
 #endif /* CONFIG_KALLSYMS */
 
+#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
+{
+       struct mod_debug *debug_info;
+       unsigned long pos, end;
+       unsigned int num_verbose;
+
+       pos = sechdrs[verboseindex].sh_addr;
+       num_verbose = sechdrs[verboseindex].sh_size /
+                               sizeof(struct mod_debug);
+       end = pos + (num_verbose * sizeof(struct mod_debug));
+
+       for (; pos < end; pos += sizeof(struct mod_debug)) {
+               debug_info = (struct mod_debug *)pos;
+               register_dynamic_debug_module(debug_info->modname,
+                       debug_info->type, debug_info->logical_modname,
+                       debug_info->flag_names, debug_info->hash,
+                       debug_info->hash2);
+       }
+}
+#else
+static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
+                                       unsigned int verboseindex)
+{
+}
+#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
+
 static void *module_alloc_update_bounds(unsigned long size)
 {
        void *ret = module_alloc(size);
@@ -1831,6 +1859,7 @@ static noinline struct module *load_module(void __user *umod,
 #endif
        unsigned int markersindex;
        unsigned int markersstringsindex;
+       unsigned int verboseindex;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -2117,6 +2146,7 @@ static noinline struct module *load_module(void __user *umod,
        markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
        markersstringsindex = find_sec(hdr, sechdrs, secstrings,
                                        "__markers_strings");
+       verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
 
        /* Now do relocations. */
        for (i = 1; i < hdr->e_shnum; i++) {
@@ -2167,6 +2197,7 @@ static noinline struct module *load_module(void __user *umod,
                marker_update_probe_range(mod->markers,
                        mod->markers + mod->num_markers);
 #endif
+       dynamic_printk_setup(sechdrs, verboseindex);
        err = module_finalize(hdr, sechdrs, mod);
        if (err < 0)
                goto cleanup;
@@ -2552,9 +2583,9 @@ static char *module_flags(struct module *mod, char *buf)
            mod->state == MODULE_STATE_GOING ||
            mod->state == MODULE_STATE_COMING) {
                buf[bx++] = '(';
-               if (mod->taints & TAINT_PROPRIETARY_MODULE)
+               if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
                        buf[bx++] = 'P';
-               if (mod->taints & TAINT_FORCED_MODULE)
+               if (mod->taints & (1 << TAINT_FORCED_MODULE))
                        buf[bx++] = 'F';
                /*
                 * TAINT_FORCED_RMMOD: could be added.
index 12c5a0a6c89bee42e44c65ee41eb4695ae180983..f290e8e866f65a636c324acfccc69954c2968bd1 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/kallsyms.h>
 
 int panic_on_oops;
-int tainted;
+static unsigned long tainted_mask;
 static int pause_on_oops;
 static int pause_on_oops_flag;
 static DEFINE_SPINLOCK(pause_on_oops_lock);
@@ -143,6 +143,26 @@ NORET_TYPE void panic(const char * fmt, ...)
 
 EXPORT_SYMBOL(panic);
 
+
+struct tnt {
+       u8 bit;
+       char true;
+       char false;
+};
+
+static const struct tnt tnts[] = {
+       { TAINT_PROPRIETARY_MODULE, 'P', 'G' },
+       { TAINT_FORCED_MODULE, 'F', ' ' },
+       { TAINT_UNSAFE_SMP, 'S', ' ' },
+       { TAINT_FORCED_RMMOD, 'R', ' ' },
+       { TAINT_MACHINE_CHECK, 'M', ' ' },
+       { TAINT_BAD_PAGE, 'B', ' ' },
+       { TAINT_USER, 'U', ' ' },
+       { TAINT_DIE, 'D', ' ' },
+       { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
+       { TAINT_WARN, 'W', ' ' },
+};
+
 /**
  *     print_tainted - return a string to represent the kernel taint state.
  *
@@ -158,32 +178,41 @@ EXPORT_SYMBOL(panic);
  *
  *     The string is overwritten by the next call to print_taint().
  */
-
 const char *print_tainted(void)
 {
-       static char buf[20];
-       if (tainted) {
-               snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c",
-                       tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
-                       tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
-                       tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
-                       tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
-                       tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
-                       tainted & TAINT_BAD_PAGE ? 'B' : ' ',
-                       tainted & TAINT_USER ? 'U' : ' ',
-                       tainted & TAINT_DIE ? 'D' : ' ',
-                       tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ',
-                       tainted & TAINT_WARN ? 'W' : ' ');
-       }
-       else
+       static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1];
+
+       if (tainted_mask) {
+               char *s;
+               int i;
+
+               s = buf + sprintf(buf, "Tainted: ");
+               for (i = 0; i < ARRAY_SIZE(tnts); i++) {
+                       const struct tnt *t = &tnts[i];
+                       *s++ = test_bit(t->bit, &tainted_mask) ?
+                                       t->true : t->false;
+               }
+               *s = 0;
+       } else
                snprintf(buf, sizeof(buf), "Not tainted");
        return(buf);
 }
 
+int test_taint(unsigned flag)
+{
+       return test_bit(flag, &tainted_mask);
+}
+EXPORT_SYMBOL(test_taint);
+
+unsigned long get_taint(void)
+{
+       return tainted_mask;
+}
+
 void add_taint(unsigned flag)
 {
        debug_locks = 0; /* can't trust the integrity of the kernel anymore */
-       tainted |= flag;
+       set_bit(flag, &tainted_mask);
 }
 EXPORT_SYMBOL(add_taint);
 
index bbd85c60f7419f5fca1cbf1d0b5d6e6aad37f625..331f9836383feaba687c89c3e4596edff76fb2fe 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/reboot.h>
 #include <linux/string.h>
 #include <linux/device.h>
+#include <linux/kmod.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
@@ -520,6 +521,10 @@ int hibernate(void)
        if (error)
                goto Exit;
 
+       error = usermodehelper_disable();
+       if (error)
+               goto Exit;
+
        /* Allocate memory management structures */
        error = create_basic_memory_bitmaps();
        if (error)
@@ -558,6 +563,7 @@ int hibernate(void)
        thaw_processes();
  Finish:
        free_basic_memory_bitmaps();
+       usermodehelper_enable();
  Exit:
        pm_notifier_call_chain(PM_POST_HIBERNATION);
        pm_restore_console();
@@ -634,6 +640,10 @@ static int software_resume(void)
        if (error)
                goto Finish;
 
+       error = usermodehelper_disable();
+       if (error)
+               goto Finish;
+
        error = create_basic_memory_bitmaps();
        if (error)
                goto Finish;
@@ -656,6 +666,7 @@ static int software_resume(void)
        thaw_processes();
  Done:
        free_basic_memory_bitmaps();
+       usermodehelper_enable();
  Finish:
        pm_notifier_call_chain(PM_POST_RESTORE);
        pm_restore_console();
index 540b16b68565e74fb9f51f68134f68cc3011b0a0..19122cf6d827d13d03e8a7520d0120d5adf92bbc 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/cpu.h>
@@ -237,6 +238,10 @@ static int suspend_prepare(void)
        if (error)
                goto Finish;
 
+       error = usermodehelper_disable();
+       if (error)
+               goto Finish;
+
        if (suspend_freeze_processes()) {
                error = -EAGAIN;
                goto Thaw;
@@ -256,6 +261,7 @@ static int suspend_prepare(void)
 
  Thaw:
        suspend_thaw_processes();
+       usermodehelper_enable();
  Finish:
        pm_notifier_call_chain(PM_POST_SUSPEND);
        pm_restore_console();
@@ -376,6 +382,7 @@ int suspend_devices_and_enter(suspend_state_t state)
 static void suspend_finish(void)
 {
        suspend_thaw_processes();
+       usermodehelper_enable();
        pm_notifier_call_chain(PM_POST_SUSPEND);
        pm_restore_console();
 }
index a6332a3132620b4563e3be8a0fbfb9639b1e5405..005b93d839ba1268da0c80c3106739ee388d996a 100644 (file)
@@ -212,13 +212,20 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
        case SNAPSHOT_FREEZE:
                if (data->frozen)
                        break;
+
                printk("Syncing filesystems ... ");
                sys_sync();
                printk("done.\n");
 
-               error = freeze_processes();
+               error = usermodehelper_disable();
                if (error)
+                       break;
+
+               error = freeze_processes();
+               if (error) {
                        thaw_processes();
+                       usermodehelper_enable();
+               }
                if (!error)
                        data->frozen = 1;
                break;
@@ -227,6 +234,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                if (!data->frozen || data->ready)
                        break;
                thaw_processes();
+               usermodehelper_enable();
                data->frozen = 0;
                break;
 
index aee891a869a4f04a4b5c72cedef14d4156da4570..6341af77eb65b559c1bf66e5cc7664b06779a694 100644 (file)
@@ -13,7 +13,7 @@
  * Fixed SMP synchronization, 08/08/99, Manfred Spraul
  *     manfred@colorfullife.com
  * Rewrote bits to get rid of console_lock
- *     01Mar01 Andrew Morton <andrewm@uow.edu.au>
+ *     01Mar01 Andrew Morton
  */
 
 #include <linux/kernel.h>
@@ -590,6 +590,8 @@ static int have_callable_console(void)
  *
  * See also:
  * printf(3)
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
  */
 
 asmlinkage int printk(const char *fmt, ...)
index cd26bed4cc26535ca7398eae07fb9b800b762f2e..a9e422df6bf63e28648432efa7f0503aa09ffe8f 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/cpu.h>
 #include <linux/highmem.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <asm/sections.h>
 #include <asm/irq_regs.h>
 #include <asm/ptrace.h>
@@ -50,11 +52,11 @@ static DEFINE_PER_CPU(int, cpu_profile_flip);
 static DEFINE_MUTEX(profile_flip_mutex);
 #endif /* CONFIG_SMP */
 
-static int __init profile_setup(char *str)
+int profile_setup(char *str)
 {
-       static char __initdata schedstr[] = "schedule";
-       static char __initdata sleepstr[] = "sleep";
-       static char __initdata kvmstr[] = "kvm";
+       static char schedstr[] = "schedule";
+       static char sleepstr[] = "sleep";
+       static char kvmstr[] = "kvm";
        int par;
 
        if (!strncmp(str, sleepstr, strlen(sleepstr))) {
@@ -100,14 +102,33 @@ static int __init profile_setup(char *str)
 __setup("profile=", profile_setup);
 
 
-void __init profile_init(void)
+int profile_init(void)
 {
+       int buffer_bytes;
        if (!prof_on)
-               return;
+               return 0;
 
        /* only text is profiled */
        prof_len = (_etext - _stext) >> prof_shift;
-       prof_buffer = alloc_bootmem(prof_len*sizeof(atomic_t));
+       buffer_bytes = prof_len*sizeof(atomic_t);
+       if (!slab_is_available()) {
+               prof_buffer = alloc_bootmem(buffer_bytes);
+               return 0;
+       }
+
+       prof_buffer = kzalloc(buffer_bytes, GFP_KERNEL);
+       if (prof_buffer)
+               return 0;
+
+       prof_buffer = alloc_pages_exact(buffer_bytes, GFP_KERNEL|__GFP_ZERO);
+       if (prof_buffer)
+               return 0;
+
+       prof_buffer = vmalloc(buffer_bytes);
+       if (prof_buffer)
+               return 0;
+
+       return -ENOMEM;
 }
 
 /* Profile event notifications */
@@ -527,7 +548,7 @@ static void __init profile_nop(void *unused)
 {
 }
 
-static int __init create_hash_tables(void)
+static int create_hash_tables(void)
 {
        int cpu;
 
@@ -575,14 +596,14 @@ out_cleanup:
 #define create_hash_tables()                   ({ 0; })
 #endif
 
-static int __init create_proc_profile(void)
+int create_proc_profile(void)
 {
        struct proc_dir_entry *entry;
 
        if (!prof_on)
                return 0;
        if (create_hash_tables())
-               return -1;
+               return -ENOMEM;
        entry = proc_create("profile", S_IWUSR | S_IRUGO,
                            NULL, &proc_profile_operations);
        if (!entry)
index 7797dae85b50b64e30d85c754ec0bc7bf9b411aa..4089d12af6e0eda2aa15cc8c145940f1bd12056c 100644 (file)
@@ -626,33 +626,34 @@ struct resource * __request_region(struct resource *parent,
 {
        struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
-       if (res) {
-               res->name = name;
-               res->start = start;
-               res->end = start + n - 1;
-               res->flags = IORESOURCE_BUSY;
+       if (!res)
+               return NULL;
 
-               write_lock(&resource_lock);
+       res->name = name;
+       res->start = start;
+       res->end = start + n - 1;
+       res->flags = IORESOURCE_BUSY;
 
-               for (;;) {
-                       struct resource *conflict;
+       write_lock(&resource_lock);
 
-                       conflict = __request_resource(parent, res);
-                       if (!conflict)
-                               break;
-                       if (conflict != parent) {
-                               parent = conflict;
-                               if (!(conflict->flags & IORESOURCE_BUSY))
-                                       continue;
-                       }
+       for (;;) {
+               struct resource *conflict;
 
-                       /* Uhhuh, that didn't work out.. */
-                       kfree(res);
-                       res = NULL;
+               conflict = __request_resource(parent, res);
+               if (!conflict)
                        break;
+               if (conflict != parent) {
+                       parent = conflict;
+                       if (!(conflict->flags & IORESOURCE_BUSY))
+                               continue;
                }
-               write_unlock(&resource_lock);
+
+               /* Uhhuh, that didn't work out.. */
+               kfree(res);
+               res = NULL;
+               break;
        }
+       write_unlock(&resource_lock);
        return res;
 }
 EXPORT_SYMBOL(__request_region);
index cb838ee93a82000bc5b313271487836e9fb5804e..3953e4aed733d32284f48ecfffa1fbff05e234c6 100644 (file)
@@ -226,7 +226,7 @@ static void check_hung_uninterruptible_tasks(int this_cpu)
         * If the system crashed already then all bets are off,
         * do not report extra hung tasks:
         */
-       if ((tainted & TAINT_DIE) || did_panic)
+       if (test_taint(TAINT_DIE) || did_panic)
                return;
 
        read_lock(&tasklist_lock);
index 234d9454294e12b6f366abd75ce70009e3cde3af..0bc8fa3c2288110b49fad4e9eaab2326f52c69f7 100644 (file)
@@ -1349,8 +1349,10 @@ asmlinkage long sys_sethostname(char __user *name, int len)
        down_write(&uts_sem);
        errno = -EFAULT;
        if (!copy_from_user(tmp, name, len)) {
-               memcpy(utsname()->nodename, tmp, len);
-               utsname()->nodename[len] = 0;
+               struct new_utsname *u = utsname();
+
+               memcpy(u->nodename, tmp, len);
+               memset(u->nodename + len, 0, sizeof(u->nodename) - len);
                errno = 0;
        }
        up_write(&uts_sem);
@@ -1362,15 +1364,17 @@ asmlinkage long sys_sethostname(char __user *name, int len)
 asmlinkage long sys_gethostname(char __user *name, int len)
 {
        int i, errno;
+       struct new_utsname *u;
 
        if (len < 0)
                return -EINVAL;
        down_read(&uts_sem);
-       i = 1 + strlen(utsname()->nodename);
+       u = utsname();
+       i = 1 + strlen(u->nodename);
        if (i > len)
                i = len;
        errno = 0;
-       if (copy_to_user(name, utsname()->nodename, i))
+       if (copy_to_user(name, u->nodename, i))
                errno = -EFAULT;
        up_read(&uts_sem);
        return errno;
@@ -1395,8 +1399,10 @@ asmlinkage long sys_setdomainname(char __user *name, int len)
        down_write(&uts_sem);
        errno = -EFAULT;
        if (!copy_from_user(tmp, name, len)) {
-               memcpy(utsname()->domainname, tmp, len);
-               utsname()->domainname[len] = 0;
+               struct new_utsname *u = utsname();
+
+               memcpy(u->domainname, tmp, len);
+               memset(u->domainname + len, 0, sizeof(u->domainname) - len);
                errno = 0;
        }
        up_write(&uts_sem);
@@ -1450,14 +1456,22 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
                return -EINVAL;
        if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
                return -EFAULT;
-       if (new_rlim.rlim_cur > new_rlim.rlim_max)
-               return -EINVAL;
        old_rlim = current->signal->rlim + resource;
        if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
            !capable(CAP_SYS_RESOURCE))
                return -EPERM;
-       if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
-               return -EPERM;
+
+       if (resource == RLIMIT_NOFILE) {
+               if (new_rlim.rlim_max == RLIM_INFINITY)
+                       new_rlim.rlim_max = sysctl_nr_open;
+               if (new_rlim.rlim_cur == RLIM_INFINITY)
+                       new_rlim.rlim_cur = sysctl_nr_open;
+               if (new_rlim.rlim_max > sysctl_nr_open)
+                       return -EPERM;
+       }
+
+       if (new_rlim.rlim_cur > new_rlim.rlim_max)
+               return -EINVAL;
 
        retval = security_task_setrlimit(resource, &new_rlim);
        if (retval)
index 503d8d4eb80acb5bc272e6dcb2be7d403955dab3..a77b27b11b048fee528e0628798f9fe8774ebbf9 100644 (file)
@@ -126,6 +126,11 @@ cond_syscall(sys_vm86);
 cond_syscall(compat_sys_ipc);
 cond_syscall(compat_sys_sysctl);
 cond_syscall(sys_flock);
+cond_syscall(sys_io_setup);
+cond_syscall(sys_io_destroy);
+cond_syscall(sys_io_submit);
+cond_syscall(sys_io_cancel);
+cond_syscall(sys_io_getevents);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
index cfc5295f1e82bc10b86b6ec6fc861b9fe4bd5ec1..617d41e4d6a08eae69152515e1ac47a9c8a3fc85 100644 (file)
@@ -149,7 +149,7 @@ extern int max_lock_depth;
 #ifdef CONFIG_PROC_SYSCTL
 static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
-static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
+static int proc_taint(struct ctl_table *table, int write, struct file *filp,
                               void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
@@ -379,10 +379,9 @@ static struct ctl_table kern_table[] = {
 #ifdef CONFIG_PROC_SYSCTL
        {
                .procname       = "tainted",
-               .data           = &tainted,
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_taint,
+               .proc_handler   = &proc_taint,
        },
 #endif
 #ifdef CONFIG_LATENCYTOP
@@ -1282,6 +1281,7 @@ static struct ctl_table fs_table[] = {
                .extra2         = &two,
        },
 #endif
+#ifdef CONFIG_AIO
        {
                .procname       = "aio-nr",
                .data           = &aio_nr,
@@ -1296,6 +1296,7 @@ static struct ctl_table fs_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_doulongvec_minmax,
        },
+#endif /* CONFIG_AIO */
 #ifdef CONFIG_INOTIFY_USER
        {
                .ctl_name       = FS_INOTIFY,
@@ -1501,7 +1502,6 @@ void register_sysctl_root(struct ctl_table_root *root)
 /* Perform the actual read/write of a sysctl table entry. */
 static int do_sysctl_strategy(struct ctl_table_root *root,
                        struct ctl_table *table,
-                       int __user *name, int nlen,
                        void __user *oldval, size_t __user *oldlenp,
                        void __user *newval, size_t newlen)
 {
@@ -1515,8 +1515,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
                return -EPERM;
 
        if (table->strategy) {
-               rc = table->strategy(table, name, nlen, oldval, oldlenp,
-                                    newval, newlen);
+               rc = table->strategy(table, oldval, oldlenp, newval, newlen);
                if (rc < 0)
                        return rc;
                if (rc > 0)
@@ -1526,8 +1525,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
        /* If there is no strategy routine, or if the strategy returns
         * zero, proceed with automatic r/w */
        if (table->data && table->maxlen) {
-               rc = sysctl_data(table, name, nlen, oldval, oldlenp,
-                                newval, newlen);
+               rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
                if (rc < 0)
                        return rc;
        }
@@ -1559,7 +1557,7 @@ repeat:
                                table = table->child;
                                goto repeat;
                        }
-                       error = do_sysctl_strategy(root, table, name, nlen,
+                       error = do_sysctl_strategy(root, table,
                                                   oldval, oldlenp,
                                                   newval, newlen);
                        return error;
@@ -2228,49 +2226,39 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
                            NULL,NULL);
 }
 
-#define OP_SET 0
-#define OP_AND 1
-#define OP_OR  2
-
-static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
-                                     int *valp,
-                                     int write, void *data)
-{
-       int op = *(int *)data;
-       if (write) {
-               int val = *negp ? -*lvalp : *lvalp;
-               switch(op) {
-               case OP_SET:    *valp = val; break;
-               case OP_AND:    *valp &= val; break;
-               case OP_OR:     *valp |= val; break;
-               }
-       } else {
-               int val = *valp;
-               if (val < 0) {
-                       *negp = -1;
-                       *lvalp = (unsigned long)-val;
-               } else {
-                       *negp = 0;
-                       *lvalp = (unsigned long)val;
-               }
-       }
-       return 0;
-}
-
 /*
- *     Taint values can only be increased
+ * Taint values can only be increased
+ * This means we can safely use a temporary.
  */
-static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
+static int proc_taint(struct ctl_table *table, int write, struct file *filp,
                               void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int op;
+       struct ctl_table t;
+       unsigned long tmptaint = get_taint();
+       int err;
 
        if (write && !capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       op = OP_OR;
-       return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
-                               do_proc_dointvec_bset_conv,&op);
+       t = *table;
+       t.data = &tmptaint;
+       err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos);
+       if (err < 0)
+               return err;
+
+       if (write) {
+               /*
+                * Poor man's atomic or. Not worth adding a primitive
+                * to everyone's atomic.h for this
+                */
+               int i;
+               for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
+                       if ((tmptaint >> i) & 1)
+                               add_taint(i);
+               }
+       }
+
+       return err;
 }
 
 struct do_proc_dointvec_minmax_conv_param {
@@ -2718,7 +2706,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
  */
 
 /* The generic sysctl data routine (used if no strategy routine supplied) */
-int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_data(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2752,7 +2740,7 @@ int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
 }
 
 /* The generic string strategy routine: */
-int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
@@ -2798,7 +2786,7 @@ int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
  * are between the minimum and maximum values given in the arrays
  * table->extra1 and table->extra2, respectively.
  */
-int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2834,7 +2822,7 @@ int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2868,7 +2856,7 @@ int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2923,35 +2911,35 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
        return error;
 }
 
-int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_data(struct ctl_table *table,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
index 8d53106a0a92c1dd619b6dc0f5e7841fc10824b4..95ed42951e0adb536db3783b5d026914ddfdbc73 100644 (file)
@@ -3,7 +3,6 @@
 #
 config TICK_ONESHOT
        bool
-       default n
 
 config NO_HZ
        bool "Tickless System (Dynamic Ticks)"
index 4ab9659d269e23bc315729f840b8742b5876e1ff..3b34b3545936dfcd179eca7f9fd2aebf4a2abfa0 100644 (file)
@@ -60,7 +60,7 @@ static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
 
 #ifdef CONFIG_SYSCTL_SYSCALL
 /* The generic string strategy routine: */
-static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen,
+static int sysctl_uts_string(ctl_table *table,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
@@ -69,8 +69,7 @@ static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen,
        write = newval && newlen;
        memcpy(&uts_table, table, sizeof(uts_table));
        uts_table.data = get_uts(table, write);
-       r = sysctl_string(&uts_table, name, nlen,
-               oldval, oldlenp, newval, newlen);
+       r = sysctl_string(&uts_table, oldval, oldlenp, newval, newlen);
        put_uts(table, write, uts_table.data);
        return r;
 }
index c275c56cf2d313e509a2aac411d3bcebf4278ca1..cd87131f2fc2aa138aa1bc818f5efab612c3085c 100644 (file)
@@ -72,12 +72,7 @@ prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
        spin_lock_irqsave(&q->lock, flags);
        if (list_empty(&wait->task_list))
                __add_wait_queue(q, wait);
-       /*
-        * don't alter the task state if this is just going to
-        * queue an async wait queue callback
-        */
-       if (is_sync_wait(wait))
-               set_current_state(state);
+       set_current_state(state);
        spin_unlock_irqrestore(&q->lock, flags);
 }
 EXPORT_SYMBOL(prepare_to_wait);
@@ -91,12 +86,7 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
        spin_lock_irqsave(&q->lock, flags);
        if (list_empty(&wait->task_list))
                __add_wait_queue_tail(q, wait);
-       /*
-        * don't alter the task state if this is just going to
-        * queue an async wait queue callback
-        */
-       if (is_sync_wait(wait))
-               set_current_state(state);
+       set_current_state(state);
        spin_unlock_irqrestore(&q->lock, flags);
 }
 EXPORT_SYMBOL(prepare_to_wait_exclusive);
index 4048e92aa04f21e7e105563fac7bf24e1be5411f..714afad46539616e4bbcab15240160ca4d188226 100644 (file)
@@ -9,7 +9,7 @@
  * Derived from the taskqueue/keventd code by:
  *
  *   David Woodhouse <dwmw2@infradead.org>
- *   Andrew Morton <andrewm@uow.edu.au>
+ *   Andrew Morton
  *   Kai Petzke <wpp@marie.physik.tu-berlin.de>
  *   Theodore Ts'o <tytso@mit.edu>
  *
index c7ad7a5b3535210df1dabe86fd1c63b888e0a7ae..85cf7ea978aafe6606e6e44cc634a82e6cf29477 100644 (file)
@@ -8,10 +8,10 @@ config BITREVERSE
        tristate
 
 config GENERIC_FIND_FIRST_BIT
-       def_bool n
+       bool
 
 config GENERIC_FIND_NEXT_BIT
-       def_bool n
+       bool
 
 config CRC_CCITT
        tristate "CRC-CCITT functions"
index aa81d2848448db8f007194cc086804dcffe2623e..31d784dd80d022cdb112fc56863eebe0cf6c5d7d 100644 (file)
@@ -807,6 +807,61 @@ menuconfig BUILD_DOCSRC
 
          Say N if you are unsure.
 
+config DYNAMIC_PRINTK_DEBUG
+       bool "Enable dynamic printk() call support"
+       default n
+       depends on PRINTK
+       select PRINTK_DEBUG
+       help
+
+         Compiles debug level messages into the kernel, which would not
+         otherwise be available at runtime. These messages can then be
+         enabled/disabled on a per module basis. This mechanism implicitly
+         enables all pr_debug() and dev_dbg() calls. The impact of this
+         compile option is a larger kernel text size of about 2%.
+
+         Usage:
+
+         Dynamic debugging is controlled by the debugfs file,
+         dynamic_printk/modules. This file contains a list of the modules that
+         can be enabled. The format of the file is the module name, followed
+         by a set of flags that can be enabled. The first flag is always the
+         'enabled' flag. For example:
+
+               <module_name> <enabled=0/1>
+                               .
+                               .
+                               .
+
+         <module_name> : Name of the module in which the debug call resides
+         <enabled=0/1> : whether the messages are enabled or not
+
+         From a live system:
+
+               snd_hda_intel enabled=0
+               fixup enabled=0
+               driver enabled=0
+
+         Enable a module:
+
+               $echo "set enabled=1 <module_name>" > dynamic_printk/modules
+
+         Disable a module:
+
+               $echo "set enabled=0 <module_name>" > dynamic_printk/modules
+
+         Enable all modules:
+
+               $echo "set enabled=1 all" > dynamic_printk/modules
+
+         Disable all modules:
+
+               $echo "set enabled=0 all" > dynamic_printk/modules
+
+         Finally, passing "dynamic_printk" at the command line enables
+         debugging for all modules. This mode can be turned off via the above
+         disable command.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
index 44001af76a7dfc4f44216fa25959291633df36e7..16feaab057b2d5fdda220ae350a09f765c7f24be 100644 (file)
@@ -81,6 +81,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
 
 obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
 
+obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
+
 hostprogs-y    := gen_crc32table
 clean-files    := crc32table.h
 
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c
new file mode 100644 (file)
index 0000000..d640f87
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * lib/dynamic_printk.c
+ *
+ * make pr_debug()/dev_dbg() calls runtime configurable based upon their
+ * their source module.
+ *
+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+
+extern struct mod_debug __start___verbose[];
+extern struct mod_debug __stop___verbose[];
+
+struct debug_name {
+       struct hlist_node hlist;
+       struct hlist_node hlist2;
+       int hash1;
+       int hash2;
+       char *name;
+       int enable;
+       int type;
+};
+
+static int nr_entries;
+static int num_enabled;
+int dynamic_enabled = DYNAMIC_ENABLED_NONE;
+static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
+       { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
+static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
+       { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
+static DECLARE_MUTEX(debug_list_mutex);
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+long long dynamic_printk_enabled;
+EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
+long long dynamic_printk_enabled2;
+EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
+
+/* returns the debug module pointer. */
+static struct debug_name *find_debug_module(char *module_name)
+{
+       int i;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct debug_name *element;
+
+       element = NULL;
+       for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
+               head = &module_table[i];
+               hlist_for_each_entry_rcu(element, node, head, hlist)
+                       if (!strcmp(element->name, module_name))
+                               return element;
+       }
+       return NULL;
+}
+
+/* returns the debug module pointer. */
+static struct debug_name *find_debug_module_hash(char *module_name, int hash)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct debug_name *element;
+
+       element = NULL;
+       head = &module_table[hash];
+       hlist_for_each_entry_rcu(element, node, head, hlist)
+               if (!strcmp(element->name, module_name))
+                       return element;
+       return NULL;
+}
+
+/* caller must hold mutex*/
+static int __add_debug_module(char *mod_name, int hash, int hash2)
+{
+       struct debug_name *new;
+       char *module_name;
+       int ret = 0;
+
+       if (find_debug_module(mod_name)) {
+               ret = -EINVAL;
+               goto out;
+       }
+       module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
+       if (!module_name) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       module_name = strcpy(module_name, mod_name);
+       module_name[strlen(mod_name)] = '\0';
+       new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
+       if (!new) {
+               kfree(module_name);
+               ret = -ENOMEM;
+               goto out;
+       }
+       INIT_HLIST_NODE(&new->hlist);
+       INIT_HLIST_NODE(&new->hlist2);
+       new->name = module_name;
+       new->hash1 = hash;
+       new->hash2 = hash2;
+       hlist_add_head_rcu(&new->hlist, &module_table[hash]);
+       hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
+       nr_entries++;
+out:
+       return ret;
+}
+
+int unregister_dynamic_debug_module(char *mod_name)
+{
+       struct debug_name *element;
+       int ret = 0;
+
+       down(&debug_list_mutex);
+       element = find_debug_module(mod_name);
+       if (!element) {
+               ret = -EINVAL;
+               goto out;
+       }
+       hlist_del_rcu(&element->hlist);
+       hlist_del_rcu(&element->hlist2);
+       synchronize_rcu();
+       kfree(element->name);
+       if (element->enable)
+               num_enabled--;
+       kfree(element);
+       nr_entries--;
+out:
+       up(&debug_list_mutex);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
+
+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
+                                       char *flags, int hash, int hash2)
+{
+       struct debug_name *elem;
+       int ret = 0;
+
+       down(&debug_list_mutex);
+       elem = find_debug_module(mod_name);
+       if (!elem) {
+               if (__add_debug_module(mod_name, hash, hash2))
+                       goto out;
+               elem = find_debug_module(mod_name);
+               if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
+                               !strcmp(mod_name, share_name)) {
+                       elem->enable = true;
+                       num_enabled++;
+               }
+       }
+       elem->type |= type;
+out:
+       up(&debug_list_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
+
+int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
+{
+       struct debug_name *elem;
+       int ret = 0;
+
+       if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
+               return 1;
+       rcu_read_lock();
+       elem = find_debug_module_hash(mod_name, hash);
+       if (elem && elem->enable)
+               ret = 1;
+       rcu_read_unlock();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
+
+static void set_all(bool enable)
+{
+       struct debug_name *e;
+       struct hlist_node *node;
+       int i;
+       long long enable_mask;
+
+       for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
+               if (module_table[i].first != NULL) {
+                       hlist_for_each_entry(e, node, &module_table[i], hlist) {
+                               e->enable = enable;
+                       }
+               }
+       }
+       if (enable)
+               enable_mask = ULLONG_MAX;
+       else
+               enable_mask = 0;
+       dynamic_printk_enabled = enable_mask;
+       dynamic_printk_enabled2 = enable_mask;
+}
+
+static int disabled_hash(int i, bool first_table)
+{
+       struct debug_name *e;
+       struct hlist_node *node;
+
+       if (first_table) {
+               hlist_for_each_entry(e, node, &module_table[i], hlist) {
+                       if (e->enable)
+                               return 0;
+               }
+       } else {
+               hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
+                       if (e->enable)
+                               return 0;
+               }
+       }
+       return 1;
+}
+
+static ssize_t pr_debug_write(struct file *file, const char __user *buf,
+                               size_t length, loff_t *ppos)
+{
+       char *buffer, *s, *value_str, *setting_str;
+       int err, value;
+       struct debug_name *elem = NULL;
+       int all = 0;
+
+       if (length > PAGE_SIZE || length < 0)
+               return -EINVAL;
+
+       buffer = (char *)__get_free_page(GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+
+       err = -EFAULT;
+       if (copy_from_user(buffer, buf, length))
+               goto out;
+
+       err = -EINVAL;
+       if (length < PAGE_SIZE)
+               buffer[length] = '\0';
+       else if (buffer[PAGE_SIZE-1])
+               goto out;
+
+       err = -EINVAL;
+       down(&debug_list_mutex);
+
+       if (strncmp("set", buffer, 3))
+               goto out_up;
+       s = buffer + 3;
+       setting_str = strsep(&s, "=");
+       if (s == NULL)
+               goto out_up;
+       setting_str = strstrip(setting_str);
+       value_str = strsep(&s, " ");
+       if (s == NULL)
+               goto out_up;
+       s = strstrip(s);
+       if (!strncmp(s, "all", 3))
+               all = 1;
+       else
+               elem = find_debug_module(s);
+       if (!strncmp(setting_str, "enable", 6)) {
+               value = !!simple_strtol(value_str, NULL, 10);
+               if (all) {
+                       if (value) {
+                               set_all(true);
+                               num_enabled = nr_entries;
+                               dynamic_enabled = DYNAMIC_ENABLED_ALL;
+                       } else {
+                               set_all(false);
+                               num_enabled = 0;
+                               dynamic_enabled = DYNAMIC_ENABLED_NONE;
+                       }
+                       err = 0;
+               } else {
+                       if (elem) {
+                               if (value && (elem->enable == 0)) {
+                                       dynamic_printk_enabled |=
+                                                       (1LL << elem->hash1);
+                                       dynamic_printk_enabled2 |=
+                                                       (1LL << elem->hash2);
+                                       elem->enable = 1;
+                                       num_enabled++;
+                                       dynamic_enabled = DYNAMIC_ENABLED_SOME;
+                                       err = 0;
+                                       printk(KERN_DEBUG
+                                              "debugging enabled for module %s",
+                                              elem->name);
+                               } else if (!value && (elem->enable == 1)) {
+                                       elem->enable = 0;
+                                       num_enabled--;
+                                       if (disabled_hash(elem->hash1, true))
+                                               dynamic_printk_enabled &=
+                                                       ~(1LL << elem->hash1);
+                                       if (disabled_hash(elem->hash2, false))
+                                               dynamic_printk_enabled2 &=
+                                                       ~(1LL << elem->hash2);
+                                       if (num_enabled)
+                                               dynamic_enabled =
+                                                       DYNAMIC_ENABLED_SOME;
+                                       else
+                                               dynamic_enabled =
+                                                       DYNAMIC_ENABLED_NONE;
+                                       err = 0;
+                                       printk(KERN_DEBUG
+                                              "debugging disabled for module "
+                                              "%s", elem->name);
+                               }
+                       }
+               }
+       }
+       if (!err)
+               err = length;
+out_up:
+       up(&debug_list_mutex);
+out:
+       free_page((unsigned long)buffer);
+       return err;
+}
+
+static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
+{
+       return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
+}
+
+static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+       (*pos)++;
+       if (*pos >= DEBUG_HASH_TABLE_SIZE)
+               return NULL;
+       return pos;
+}
+
+static void pr_debug_seq_stop(struct seq_file *s, void *v)
+{
+       /* Nothing to do */
+}
+
+static int pr_debug_seq_show(struct seq_file *s, void *v)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct debug_name *elem;
+       unsigned int i = *(loff_t *) v;
+
+       rcu_read_lock();
+       head = &module_table[i];
+       hlist_for_each_entry_rcu(elem, node, head, hlist) {
+               seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
+               seq_printf(s, "\n");
+       }
+       rcu_read_unlock();
+       return 0;
+}
+
+static struct seq_operations pr_debug_seq_ops = {
+       .start = pr_debug_seq_start,
+       .next  = pr_debug_seq_next,
+       .stop  = pr_debug_seq_stop,
+       .show  = pr_debug_seq_show
+};
+
+static int pr_debug_open(struct inode *inode, struct file *filp)
+{
+       return seq_open(filp, &pr_debug_seq_ops);
+}
+
+static const struct file_operations pr_debug_operations = {
+       .open           = pr_debug_open,
+       .read           = seq_read,
+       .write          = pr_debug_write,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init dynamic_printk_init(void)
+{
+       struct dentry *dir, *file;
+       struct mod_debug *iter;
+       unsigned long value;
+
+       dir = debugfs_create_dir("dynamic_printk", NULL);
+       if (!dir)
+               return -ENOMEM;
+       file = debugfs_create_file("modules", 0644, dir, NULL,
+                                       &pr_debug_operations);
+       if (!file) {
+               debugfs_remove(dir);
+               return -ENOMEM;
+       }
+       for (value = (unsigned long)__start___verbose;
+               value < (unsigned long)__stop___verbose;
+               value += sizeof(struct mod_debug)) {
+                       iter = (struct mod_debug *)value;
+                       register_dynamic_debug_module(iter->modname,
+                               iter->type,
+                               iter->logical_modname,
+                               iter->flag_names, iter->hash, iter->hash2);
+       }
+       return 0;
+}
+module_init(dynamic_printk_init);
+/* may want to move this earlier so we can get traces as early as possible */
+
+static int __init dynamic_printk_setup(char *str)
+{
+       if (str)
+               return -ENOENT;
+       set_all(true);
+       return 0;
+}
+/* Use early_param(), so we can get debug output as early as possible */
+early_param("dynamic_printk", dynamic_printk_setup);
index 5d90074dca7550f4935e71127911441c9bc617e2..75dbda03f4fb99a92ef8cc3ead817afefd707702 100644 (file)
@@ -79,3 +79,12 @@ void iommu_area_free(unsigned long *map, unsigned long start, unsigned int nr)
        }
 }
 EXPORT_SYMBOL(iommu_area_free);
+
+unsigned long iommu_num_pages(unsigned long addr, unsigned long len,
+                             unsigned long io_page_size)
+{
+       unsigned long size = (addr & (io_page_size - 1)) + len;
+
+       return DIV_ROUND_UP(size, io_page_size);
+}
+EXPORT_SYMBOL(iommu_num_pages);
index fbf0ae28237672a6fafdbbf29e481d76c45ddd11..0487d1f64806c645927fdc22ea4a5848f3d9ea5f 100644 (file)
@@ -387,11 +387,17 @@ EXPORT_SYMBOL_GPL(kobject_init_and_add);
  * kobject_rename - change the name of an object
  * @kobj: object in question.
  * @new_name: object's new name
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of kobject_rename
+ * on the same kobject and to ensure that new_name is valid and
+ * won't conflict with other kobjects.
  */
 int kobject_rename(struct kobject *kobj, const char *new_name)
 {
        int error = 0;
        const char *devpath = NULL;
+       const char *dup_name = NULL, *name;
        char *devpath_string = NULL;
        char *envp[2];
 
@@ -401,19 +407,6 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
        if (!kobj->parent)
                return -EINVAL;
 
-       /* see if this name is already in use */
-       if (kobj->kset) {
-               struct kobject *temp_kobj;
-               temp_kobj = kset_find_obj(kobj->kset, new_name);
-               if (temp_kobj) {
-                       printk(KERN_WARNING "kobject '%s' cannot be renamed "
-                              "to '%s' as '%s' is already in existence.\n",
-                              kobject_name(kobj), new_name, new_name);
-                       kobject_put(temp_kobj);
-                       return -EINVAL;
-               }
-       }
-
        devpath = kobject_get_path(kobj, GFP_KERNEL);
        if (!devpath) {
                error = -ENOMEM;
@@ -428,15 +421,27 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
        envp[0] = devpath_string;
        envp[1] = NULL;
 
+       name = dup_name = kstrdup(new_name, GFP_KERNEL);
+       if (!name) {
+               error = -ENOMEM;
+               goto out;
+       }
+
        error = sysfs_rename_dir(kobj, new_name);
+       if (error)
+               goto out;
+
+       /* Install the new kobject name */
+       dup_name = kobj->name;
+       kobj->name = name;
 
        /* This function is mostly/only used for network interface.
         * Some hotplug package track interfaces by their name and
         * therefore want to know when the name is changed by the user. */
-       if (!error)
-               kobject_uevent_env(kobj, KOBJ_MOVE, envp);
+       kobject_uevent_env(kobj, KOBJ_MOVE, envp);
 
 out:
+       kfree(dup_name);
        kfree(devpath_string);
        kfree(devpath);
        kobject_put(kobj);
index c399bc1093cbedb276f3e974353534560197e940..cceecb6a963d1638bd420a82f7a3b85014cea379 100644 (file)
 /* Works only for digits and letters, but small and fast */
 #define TOLOWER(x) ((x) | 0x20)
 
+static unsigned int simple_guess_base(const char *cp)
+{
+       if (cp[0] == '0') {
+               if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
+                       return 16;
+               else
+                       return 8;
+       } else {
+               return 10;
+       }
+}
+
 /**
  * simple_strtoul - convert a string to an unsigned long
  * @cp: The start of the string
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
 {
-       unsigned long result = 0,value;
+       unsigned long result = 0;
 
-       if (!base) {
-               base = 10;
-               if (*cp == '0') {
-                       base = 8;
-                       cp++;
-                       if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
-                               cp++;
-                               base = 16;
-                       }
-               }
-       } else if (base == 16) {
-               if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
-                       cp += 2;
-       }
-       while (isxdigit(*cp) &&
-              (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
-               result = result*base + value;
+       if (!base)
+               base = simple_guess_base(cp);
+
+       if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
+               cp += 2;
+
+       while (isxdigit(*cp)) {
+               unsigned int value;
+
+               value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
+               if (value >= base)
+                       break;
+               result = result * base + value;
                cp++;
        }
+
        if (endp)
                *endp = (char *)cp;
        return result;
 }
-
 EXPORT_SYMBOL(simple_strtoul);
 
 /**
@@ -74,13 +82,12 @@ EXPORT_SYMBOL(simple_strtoul);
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-long simple_strtol(const char *cp,char **endp,unsigned int base)
+long simple_strtol(const char *cp, char **endp, unsigned int base)
 {
-       if(*cp=='-')
-               return -simple_strtoul(cp+1,endp,base);
-       return simple_strtoul(cp,endp,base);
+       if(*cp == '-')
+               return -simple_strtoul(cp + 1, endp, base);
+       return simple_strtoul(cp, endp, base);
 }
-
 EXPORT_SYMBOL(simple_strtol);
 
 /**
@@ -89,34 +96,30 @@ EXPORT_SYMBOL(simple_strtol);
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
+unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
 {
-       unsigned long long result = 0,value;
+       unsigned long long result = 0;
 
-       if (!base) {
-               base = 10;
-               if (*cp == '0') {
-                       base = 8;
-                       cp++;
-                       if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
-                               cp++;
-                               base = 16;
-                       }
-               }
-       } else if (base == 16) {
-               if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
-                       cp += 2;
-       }
-       while (isxdigit(*cp)
-        && (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
-               result = result*base + value;
+       if (!base)
+               base = simple_guess_base(cp);
+
+       if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
+               cp += 2;
+
+       while (isxdigit(*cp)) {
+               unsigned int value;
+
+               value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
+               if (value >= base)
+                       break;
+               result = result * base + value;
                cp++;
        }
+
        if (endp)
                *endp = (char *)cp;
        return result;
 }
-
 EXPORT_SYMBOL(simple_strtoull);
 
 /**
@@ -125,14 +128,13 @@ EXPORT_SYMBOL(simple_strtoull);
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+long long simple_strtoll(const char *cp, char **endp, unsigned int base)
 {
        if(*cp=='-')
-               return -simple_strtoull(cp+1,endp,base);
-       return simple_strtoull(cp,endp,base);
+               return -simple_strtoull(cp + 1, endp, base);
+       return simple_strtoull(cp, endp, base);
 }
 
-
 /**
  * strict_strtoul - convert a string to an unsigned long strictly
  * @cp: The string to be converted
@@ -155,7 +157,27 @@ long long simple_strtoll(const char *cp,char **endp,unsigned int base)
  * simple_strtoul just ignores the successive invalid characters and
  * return the converted value of prefix part of the string.
  */
-int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
+int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
+{
+       char *tail;
+       unsigned long val;
+       size_t len;
+
+       *res = 0;
+       len = strlen(cp);
+       if (len == 0)
+               return -EINVAL;
+
+       val = simple_strtoul(cp, &tail, base);
+       if ((*tail == '\0') ||
+               ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
+               *res = val;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL(strict_strtoul);
 
 /**
  * strict_strtol - convert a string to a long strictly
@@ -169,7 +191,20 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
  * It returns 0 if conversion is successful and *res is set to the converted
  * value, otherwise it returns -EINVAL and *res is set to 0.
  */
-int strict_strtol(const char *cp, unsigned int base, long *res);
+int strict_strtol(const char *cp, unsigned int base, long *res)
+{
+       int ret;
+       if (*cp == '-') {
+               ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
+               if (!ret)
+                       *res = -(*res);
+       } else {
+               ret = strict_strtoul(cp, base, (unsigned long *)res);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(strict_strtol);
 
 /**
  * strict_strtoull - convert a string to an unsigned long long strictly
@@ -193,7 +228,27 @@ int strict_strtol(const char *cp, unsigned int base, long *res);
  * simple_strtoull just ignores the successive invalid characters and
  * return the converted value of prefix part of the string.
  */
-int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
+int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
+{
+       char *tail;
+       unsigned long long val;
+       size_t len;
+
+       *res = 0;
+       len = strlen(cp);
+       if (len == 0)
+               return -EINVAL;
+
+       val = simple_strtoull(cp, &tail, base);
+       if ((*tail == '\0') ||
+               ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
+               *res = val;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL(strict_strtoull);
 
 /**
  * strict_strtoll - convert a string to a long long strictly
@@ -207,53 +262,20 @@ int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
  * It returns 0 if conversion is successful and *res is set to the converted
  * value, otherwise it returns -EINVAL and *res is set to 0.
  */
-int strict_strtoll(const char *cp, unsigned int base, long long *res);
-
-#define define_strict_strtoux(type, valtype)                           \
-int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\
-{                                                                      \
-       char *tail;                                                     \
-       valtype val;                                                    \
-       size_t len;                                                     \
-                                                                       \
-       *res = 0;                                                       \
-       len = strlen(cp);                                               \
-       if (len == 0)                                                   \
-               return -EINVAL;                                         \
-                                                                       \
-       val = simple_strtou##type(cp, &tail, base);                     \
-       if ((*tail == '\0') ||                                          \
-               ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
-               *res = val;                                             \
-               return 0;                                               \
-       }                                                               \
-                                                                       \
-       return -EINVAL;                                                 \
-}                                                                      \
-
-#define define_strict_strtox(type, valtype)                            \
-int strict_strto##type(const char *cp, unsigned int base, valtype *res)        \
-{                                                                      \
-       int ret;                                                        \
-       if (*cp == '-') {                                               \
-               ret = strict_strtou##type(cp+1, base, res);             \
-               if (!ret)                                               \
-                       *res = -(*res);                                 \
-       } else                                                          \
-               ret = strict_strtou##type(cp, base, res);               \
-                                                                       \
-       return ret;                                                     \
-}                                                                      \
-
-define_strict_strtoux(l, unsigned long)
-define_strict_strtox(l, long)
-define_strict_strtoux(ll, unsigned long long)
-define_strict_strtox(ll, long long)
+int strict_strtoll(const char *cp, unsigned int base, long long *res)
+{
+       int ret;
+       if (*cp == '-') {
+               ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
+               if (!ret)
+                       *res = -(*res);
+       } else {
+               ret = strict_strtoull(cp, base, (unsigned long long *)res);
+       }
 
-EXPORT_SYMBOL(strict_strtoul);
-EXPORT_SYMBOL(strict_strtol);
+       return ret;
+}
 EXPORT_SYMBOL(strict_strtoll);
-EXPORT_SYMBOL(strict_strtoull);
 
 static int skip_atoi(const char **s)
 {
@@ -565,6 +587,10 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
  * @fmt: The format string to use
  * @args: Arguments for the format string
  *
+ * This function follows C99 vsnprintf, but has some extensions:
+ * %pS output the name of a text symbol
+ * %pF output the name of a function pointer
+ *
  * The return value is the number of characters which would
  * be generated for the given input, excluding the trailing
  * '\0', as per ISO C99. If you want to have the exact
@@ -790,7 +816,6 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
        /* the trailing null byte doesn't count towards the total */
        return str-buf;
 }
-
 EXPORT_SYMBOL(vsnprintf);
 
 /**
@@ -806,6 +831,8 @@ EXPORT_SYMBOL(vsnprintf);
  *
  * Call this function if you are already dealing with a va_list.
  * You probably want scnprintf() instead.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
  */
 int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
 {
@@ -814,7 +841,6 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
        i=vsnprintf(buf,size,fmt,args);
        return (i >= size) ? (size - 1) : i;
 }
-
 EXPORT_SYMBOL(vscnprintf);
 
 /**
@@ -828,6 +854,8 @@ EXPORT_SYMBOL(vscnprintf);
  * generated for the given input, excluding the trailing null,
  * as per ISO C99.  If the return is greater than or equal to
  * @size, the resulting string is truncated.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
  */
 int snprintf(char * buf, size_t size, const char *fmt, ...)
 {
@@ -839,7 +867,6 @@ int snprintf(char * buf, size_t size, const char *fmt, ...)
        va_end(args);
        return i;
 }
-
 EXPORT_SYMBOL(snprintf);
 
 /**
@@ -877,12 +904,13 @@ EXPORT_SYMBOL(scnprintf);
  *
  * Call this function if you are already dealing with a va_list.
  * You probably want sprintf() instead.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
  */
 int vsprintf(char *buf, const char *fmt, va_list args)
 {
        return vsnprintf(buf, INT_MAX, fmt, args);
 }
-
 EXPORT_SYMBOL(vsprintf);
 
 /**
@@ -894,6 +922,8 @@ EXPORT_SYMBOL(vsprintf);
  * The function returns the number of characters written
  * into @buf. Use snprintf() or scnprintf() in order to avoid
  * buffer overflows.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
  */
 int sprintf(char * buf, const char *fmt, ...)
 {
@@ -905,7 +935,6 @@ int sprintf(char * buf, const char *fmt, ...)
        va_end(args);
        return i;
 }
-
 EXPORT_SYMBOL(sprintf);
 
 /**
@@ -1134,7 +1163,6 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
 
        return num;
 }
-
 EXPORT_SYMBOL(vsscanf);
 
 /**
@@ -1153,5 +1181,4 @@ int sscanf(const char * buf, const char * fmt, ...)
        va_end(args);
        return i;
 }
-
 EXPORT_SYMBOL(sscanf);
index 91ee3922510aef5d27d91ad49a01cae866ccf390..1a501a4de95cba98543bf706d8c8078ce598d3cd 100644 (file)
@@ -101,7 +101,7 @@ config HAVE_MEMORY_PRESENT
 # with gcc 3.4 and later.
 #
 config SPARSEMEM_STATIC
-       def_bool n
+       bool
 
 #
 # Architecture platforms which require a two level mem_section in SPARSEMEM
@@ -113,7 +113,7 @@ config SPARSEMEM_EXTREME
        depends on SPARSEMEM && !SPARSEMEM_STATIC
 
 config SPARSEMEM_VMEMMAP_ENABLE
-       def_bool n
+       bool
 
 config SPARSEMEM_VMEMMAP
        bool "Sparse Memory virtual memmap"
index ad8eec6e44a85a9593c781ce252b127cb96992cd..ac5a891f142a8176dc7c3fdd2592ef6c89511dec 100644 (file)
@@ -48,7 +48,7 @@ early_param("bootmem_debug", bootmem_debug_setup);
        if (unlikely(bootmem_debug))                    \
                printk(KERN_INFO                        \
                        "bootmem::%s " fmt,             \
-                       __FUNCTION__, ## args);         \
+                       __func__, ## args);             \
 })
 
 static unsigned long __init bootmap_bytes(unsigned long pages)
index 343cfdfebd9ea0931b9ac6c4e91ed61ba0262730..a1da969bd9803cf334c3c5c1e9746e96eba1f377 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2002, Linus Torvalds
  *
- * 11Jan2003   akpm@digeo.com
+ * 11Jan2003   Andrew Morton
  *             Initial version.
  */
 
index 494ff20b6cfa7c66291e4fbfc425de0e477322da..903bf316912a68882dadfb0144aef035a6bd5fda 100644 (file)
@@ -1187,8 +1187,7 @@ out:
        ra->prev_pos |= prev_offset;
 
        *ppos = ((loff_t)index << PAGE_CACHE_SHIFT) + offset;
-       if (filp)
-               file_accessed(filp);
+       file_accessed(filp);
 }
 
 int file_read_actor(read_descriptor_t *desc, struct page *page,
index 67a71191136ed8f6ad9dad03b472440baa322210..38633864a93e874009d9e6aa00619cf7471b0d9e 100644 (file)
@@ -2008,7 +2008,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        entry = huge_ptep_get(ptep);
        if (huge_pte_none(entry)) {
                ret = hugetlb_no_page(mm, vma, address, ptep, write_access);
-               goto out_unlock;
+               goto out_mutex;
        }
 
        ret = 0;
@@ -2024,7 +2024,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        if (write_access && !pte_write(entry)) {
                if (vma_needs_reservation(h, vma, address) < 0) {
                        ret = VM_FAULT_OOM;
-                       goto out_unlock;
+                       goto out_mutex;
                }
 
                if (!(vma->vm_flags & VM_SHARED))
@@ -2034,10 +2034,23 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 
        spin_lock(&mm->page_table_lock);
        /* Check for a racing update before calling hugetlb_cow */
-       if (likely(pte_same(entry, huge_ptep_get(ptep))))
-               if (write_access && !pte_write(entry))
+       if (unlikely(!pte_same(entry, huge_ptep_get(ptep))))
+               goto out_page_table_lock;
+
+
+       if (write_access) {
+               if (!pte_write(entry)) {
                        ret = hugetlb_cow(mm, vma, address, ptep, entry,
                                                        pagecache_page);
+                       goto out_page_table_lock;
+               }
+               entry = pte_mkdirty(entry);
+       }
+       entry = pte_mkyoung(entry);
+       if (huge_ptep_set_access_flags(vma, address, ptep, entry, write_access))
+               update_mmu_cache(vma, address, entry);
+
+out_page_table_lock:
        spin_unlock(&mm->page_table_lock);
 
        if (pagecache_page) {
@@ -2045,7 +2058,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                put_page(pagecache_page);
        }
 
-out_unlock:
+out_mutex:
        mutex_unlock(&hugetlb_instantiation_mutex);
 
        return ret;
index 24de8b65fdbd1f3cd26fafe888277401125c7bc9..c130a137c12938cb0d7baa3ac6a9b8f333beb53c 100644 (file)
@@ -7,7 +7,7 @@
  * Contains functions related to writing back dirty pages at the
  * address_space level.
  *
- * 10Apr2002   akpm@zip.com.au
+ * 10Apr2002   Andrew Morton
  *             Initial version
  */
 
index 27b8681139fdb71e4d0da204ecc4a65fc3f7a1b5..9eb9eb92828510efbc7100addea5fa766c8f48ea 100644 (file)
@@ -3952,7 +3952,7 @@ static void check_for_regular_memory(pg_data_t *pgdat)
 void __init free_area_init_nodes(unsigned long *max_zone_pfn)
 {
        unsigned long nid;
-       enum zone_type i;
+       int i;
 
        /* Sort early_node_map as initialisation assumes it is sorted */
        sort_node_map();
index 0cbe0c60c6bff39d60f0f3994258de7931d6dd4d..a0a14c4d5072dbeef4f68c9ba37ea771e4f38577 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2002, Linus Torvalds.
  *
- * 09Apr2002   akpm@zip.com.au
+ * 09Apr2002   Andrew Morton
  *             Initial version
  * 29Feb2004   kaos@sgi.com
  *             Move worker thread creation to kthread to avoid chewing
index 77e8ddf945e9a725d4b675923124f4eafd0924e2..6cbd9a72fde2c8c1e20bd1c3da9144fa0d13d65c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2002, Linus Torvalds
  *
- * 09Apr2002   akpm@zip.com.au
+ * 09Apr2002   Andrew Morton
  *             Initial version.
  */
 
index 6650c1d878b463a114e0e024688ecdc1d0fa6b74..e83e4b114ef12b78c74480cd0ddaa6b4369d3b4c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2002, Linus Torvalds
  *
- * 10Sep2002   akpm@zip.com.au
+ * 10Sep2002   Andrew Morton
  *             Initial version.
  */
 
index cb3475ea6fdada58337e7bf6e39773478afb0b7b..34cf1ee014b8a10e668408052ff916916630906c 100644 (file)
@@ -82,13 +82,13 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev,
 
 static int fc_rebuild_header(struct sk_buff *skb)
 {
+#ifdef CONFIG_INET
        struct fch_hdr *fch=(struct fch_hdr *)skb->data;
        struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr));
        if(fcllc->ethertype != htons(ETH_P_IP)) {
                printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype));
                return 0;
        }
-#ifdef CONFIG_INET
        return arp_find(fch->daddr, skb);
 #else
        return 0;
index 366d3e9d51f8ed49dbac3708c90c2de28d5c9f3a..ba6f73eb06c60c1a7f44e90eacfe5c130819ddd8 100644 (file)
@@ -4,6 +4,7 @@
 
 menuconfig BRIDGE_NF_EBTABLES
        tristate "Ethernet Bridge tables (ebtables) support"
+       depends on BRIDGE && BRIDGE_NETFILTER
        select NETFILTER_XTABLES
        help
          ebtables is a general, extensible frame/packet identification
index b0dc818a91d7fadafb9ea7308fa66f1140ca45a4..f1d07b5c1e17257c21f6669588946a0df08b77a4 100644 (file)
@@ -96,7 +96,7 @@ static void net_free(struct net *net)
                return;
        }
 #endif
-
+       kfree(net->gen);
        kmem_cache_free(net_cachep, net);
 }
 
index 2f0ac3c3eb710e409ee41323b22f6f64fa2a5342..8008c8613027cd05c20ce3b6d8b6066bc14a3109 100644 (file)
@@ -152,7 +152,7 @@ static struct dn_dev_parms dn_dev_list[] =  {
 
 #define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
 
-#define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x))
+#define DN_DEV_PARMS_OFFSET(x) offsetof(struct dn_dev_parms, x)
 
 #ifdef CONFIG_SYSCTL
 
@@ -166,7 +166,7 @@ static int max_priority[] = { 127 }; /* From DECnet spec */
 
 static int dn_forwarding_proc(ctl_table *, int, struct file *,
                        void __user *, size_t *, loff_t *);
-static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+static int dn_forwarding_sysctl(ctl_table *table,
                        void __user *oldval, size_t __user *oldlenp,
                        void __user *newval, size_t newlen);
 
@@ -318,7 +318,7 @@ static int dn_forwarding_proc(ctl_table *table, int write,
 #endif
 }
 
-static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+static int dn_forwarding_sysctl(ctl_table *table,
                        void __user *oldval, size_t __user *oldlenp,
                        void __user *newval, size_t newlen)
 {
index 228067c571ba2aaf379463a609c822a2f6797861..36400b2668967c1bb5e4eab723837f78566641f8 100644 (file)
@@ -132,7 +132,7 @@ static int parse_addr(__le16 *addr, char *str)
 }
 
 
-static int dn_node_address_strategy(ctl_table *table, int __user *name, int nlen,
+static int dn_node_address_strategy(ctl_table *table,
                                void __user *oldval, size_t __user *oldlenp,
                                void __user *newval, size_t newlen)
 {
@@ -217,7 +217,7 @@ static int dn_node_address_handler(ctl_table *table, int write,
 }
 
 
-static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen,
+static int dn_def_dev_strategy(ctl_table *table,
                                void __user *oldval, size_t __user *oldlenp,
                                void __user *newval, size_t newlen)
 {
index b12dae2b0b2dbcc527eee09a5d7309ffd4852ebc..5154e729cf161401d644125f359aa1a9f77f139b 100644 (file)
@@ -1283,7 +1283,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
        return ret;
 }
 
-static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
+static int devinet_conf_sysctl(ctl_table *table,
                               void __user *oldval, size_t __user *oldlenp,
                               void __user *newval, size_t newlen)
 {
@@ -1379,12 +1379,11 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
        return ret;
 }
 
-int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
+int ipv4_doint_and_flush_strategy(ctl_table *table,
                                  void __user *oldval, size_t __user *oldlenp,
                                  void __user *newval, size_t newlen)
 {
-       int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
-                                     newval, newlen);
+       int ret = devinet_conf_sysctl(table, oldval, oldlenp, newval, newlen);
        struct net *net = table->extra2;
 
        if (ret == 1)
index aa2c50a180f7ea0d194992321dd60797e7859812..fa2d6b6fc3e581524181d88a1402df6289eb42c8 100644 (file)
@@ -41,12 +41,13 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
                                          int (*okfn)(struct sk_buff *))
 {
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
        /* Previously seen (loopback)?  Ignore.  Do this before
           fragment check. */
        if (skb->nfct)
                return NF_ACCEPT;
 #endif
-
+#endif
        /* Gather fragments. */
        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
                if (nf_ct_ipv4_gather_frags(skb,
index 2ac9eaf1a8c92bfbcf546ae26c81a09aeb899551..a65cf692359fbc803032a2d9a18dead804747bc0 100644 (file)
@@ -584,6 +584,98 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
        .flags          = NF_CT_EXT_F_PREALLOC,
 };
 
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+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 },
+};
+
+static int nfnetlink_parse_nat_proto(struct nlattr *attr,
+                                    const struct nf_conn *ct,
+                                    struct nf_nat_range *range)
+{
+       struct nlattr *tb[CTA_PROTONAT_MAX+1];
+       const struct nf_nat_protocol *npt;
+       int err;
+
+       err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
+       if (err < 0)
+               return err;
+
+       npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
+       if (npt->nlattr_to_range)
+               err = npt->nlattr_to_range(tb, range);
+       nf_nat_proto_put(npt);
+       return err;
+}
+
+static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
+       [CTA_NAT_MINIP]         = { .type = NLA_U32 },
+       [CTA_NAT_MAXIP]         = { .type = NLA_U32 },
+};
+
+static int
+nfnetlink_parse_nat(struct nlattr *nat,
+                   const struct nf_conn *ct, struct nf_nat_range *range)
+{
+       struct nlattr *tb[CTA_NAT_MAX+1];
+       int err;
+
+       memset(range, 0, sizeof(*range));
+
+       err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[CTA_NAT_MINIP])
+               range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
+
+       if (!tb[CTA_NAT_MAXIP])
+               range->max_ip = range->min_ip;
+       else
+               range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
+
+       if (range->min_ip)
+               range->flags |= IP_NAT_RANGE_MAP_IPS;
+
+       if (!tb[CTA_NAT_PROTO])
+               return 0;
+
+       err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+                         enum nf_nat_manip_type manip,
+                         struct nlattr *attr)
+{
+       struct nf_nat_range range;
+
+       if (nfnetlink_parse_nat(attr, ct, &range) < 0)
+               return -EINVAL;
+       if (nf_nat_initialized(ct, manip))
+               return -EEXIST;
+
+       return nf_nat_setup_info(ct, &range, manip);
+}
+#else
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+                         enum nf_nat_manip_type manip,
+                         struct nlattr *attr)
+{
+       return -EOPNOTSUPP;
+}
+#endif
+
 static int __net_init nf_nat_net_init(struct net *net)
 {
        net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
@@ -654,6 +746,9 @@ static int __init nf_nat_init(void)
 
        BUG_ON(nf_nat_seq_adjust_hook != NULL);
        rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
+       BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
+       rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
+                          nfnetlink_parse_nat_setup);
        return 0;
 
  cleanup_extend:
@@ -667,10 +762,12 @@ static void __exit nf_nat_cleanup(void)
        nf_ct_l3proto_put(l3proto);
        nf_ct_extend_unregister(&nat_extend);
        rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
+       rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
        synchronize_net();
 }
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("nf-nat-ipv4");
 
 module_init(nf_nat_init);
 module_exit(nf_nat_cleanup);
index a6d7c584f53b9a4f7493ac3b73b2e4b2602f66bf..942be04e795571084c71abbde6060600ad3b348d 100644 (file)
@@ -2908,8 +2908,6 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
 }
 
 static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
-                                               int __user *name,
-                                               int nlen,
                                                void __user *oldval,
                                                size_t __user *oldlenp,
                                                void __user *newval,
@@ -2972,16 +2970,13 @@ static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
 }
 
 static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
-                                                  int __user *name,
-                                                  int nlen,
                                                   void __user *oldval,
                                                   size_t __user *oldlenp,
                                                   void __user *newval,
                                                   size_t newlen)
 {
        int old = ip_rt_secret_interval;
-       int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
-                                newlen);
+       int ret = sysctl_jiffies(table, oldval, oldlenp, newval, newlen);
 
        rt_secret_reschedule(old);
 
index 276d047fb85a94eccf402ab17dc043809884f790..1bb10df8ce7dd94b89a0b43b170307557cf521f0 100644 (file)
@@ -64,8 +64,8 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
 }
 
 /* Validate changes from sysctl interface. */
-static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
-                                        int nlen, void __user *oldval,
+static int ipv4_sysctl_local_port_range(ctl_table *table,
+                                        void __user *oldval,
                                         size_t __user *oldlenp,
                                        void __user *newval, size_t newlen)
 {
@@ -80,7 +80,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
        };
 
        inet_get_local_port_range(range, range + 1);
-       ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
+       ret = sysctl_intvec(&tmp, oldval, oldlenp, newval, newlen);
        if (ret == 0 && newval && newlen) {
                if (range[1] < range[0])
                        ret = -EINVAL;
@@ -109,8 +109,8 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file *
        return ret;
 }
 
-static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
-                                        int nlen, void __user *oldval,
+static int sysctl_tcp_congestion_control(ctl_table *table,
+                                        void __user *oldval,
                                         size_t __user *oldlenp,
                                         void __user *newval, size_t newlen)
 {
@@ -122,7 +122,7 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
        int ret;
 
        tcp_get_default_congestion_control(val);
-       ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
+       ret = sysctl_string(&tbl, oldval, oldlenp, newval, newlen);
        if (ret == 1 && newval && newlen)
                ret = tcp_set_default_congestion_control(val);
        return ret;
@@ -165,8 +165,8 @@ static int proc_allowed_congestion_control(ctl_table *ctl,
        return ret;
 }
 
-static int strategy_allowed_congestion_control(ctl_table *table, int __user *name,
-                                              int nlen, void __user *oldval,
+static int strategy_allowed_congestion_control(ctl_table *table,
+                                              void __user *oldval,
                                               size_t __user *oldlenp,
                                               void __user *newval,
                                               size_t newlen)
@@ -179,7 +179,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
                return -ENOMEM;
 
        tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
-       ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
+       ret = sysctl_string(&tbl, oldval, oldlenp, newval, newlen);
        if (ret == 1 && newval && newlen)
                ret = tcp_set_allowed_congestion_control(tbl.data);
        kfree(tbl.data);
index 7b6a584b62ddbcbac75ba193fe04cfebc26357da..eea9542728ca79b76b3c20427f74f9a5cad95079 100644 (file)
@@ -3982,7 +3982,6 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
 }
 
 static int addrconf_sysctl_forward_strategy(ctl_table *table,
-                                           int __user *name, int nlen,
                                            void __user *oldval,
                                            size_t __user *oldlenp,
                                            void __user *newval, size_t newlen)
index 840b15780a366a7d09e8df994eabc0ddb9752f13..172438320eec74287b045cd6b784bb3de0b38b0f 100644 (file)
@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
                }
                neigh->flags |= NTF_ROUTER;
        } else if (rt) {
-               rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
+               rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
        }
 
        if (rt)
@@ -1730,9 +1730,8 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f
        return ret;
 }
 
-int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
-                                int nlen, void __user *oldval,
-                                size_t __user *oldlenp,
+int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl,
+                                void __user *oldval, size_t __user *oldlenp,
                                 void __user *newval, size_t newlen)
 {
        struct net_device *dev = ctl->extra1;
@@ -1745,13 +1744,11 @@ int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
 
        switch (ctl->ctl_name) {
        case NET_NEIGH_REACHABLE_TIME:
-               ret = sysctl_jiffies(ctl, name, nlen,
-                                    oldval, oldlenp, newval, newlen);
+               ret = sysctl_jiffies(ctl, oldval, oldlenp, newval, newlen);
                break;
        case NET_NEIGH_RETRANS_TIME_MS:
        case NET_NEIGH_REACHABLE_TIME_MS:
-                ret = sysctl_ms_jiffies(ctl, name, nlen,
-                                        oldval, oldlenp, newval, newlen);
+                ret = sysctl_ms_jiffies(ctl, oldval, oldlenp, newval, newlen);
                 break;
        default:
                ret = 0;
index 6b29b03925f1f08ec7013a969c64511a8c228f13..fd5b3a4e332988056119748ae1c636dff72b53b9 100644 (file)
@@ -12,6 +12,7 @@
 
 int ip6_route_me_harder(struct sk_buff *skb)
 {
+       struct net *net = dev_net(skb->dst->dev);
        struct ipv6hdr *iph = ipv6_hdr(skb);
        struct dst_entry *dst;
        struct flowi fl = {
@@ -23,7 +24,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
                    .saddr = iph->saddr, } },
        };
 
-       dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
+       dst = ip6_route_output(net, skb->sk, &fl);
 
 #ifdef CONFIG_XFRM
        if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
@@ -33,8 +34,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
 #endif
 
        if (dst->error) {
-               IP6_INC_STATS(&init_net, ip6_dst_idev(dst),
-                             IPSTATS_MIB_OUTNOROUTES);
+               IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
                LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
                dst_release(dst);
                return -EINVAL;
index 2a451562377608788b5e7ece2beac917320dca43..2ad504fc3414e19eb1b43cef909af2a68214de4b 100644 (file)
@@ -545,8 +545,12 @@ static int netdev_notify(struct notifier_block *nb,
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       sprintf(buf, "netdev:%s", dev->name);
        dir = sdata->debugfsdir;
+
+       if (!dir)
+               return 0;
+
+       sprintf(buf, "netdev:%s", dev->name);
        if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
                printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
                       "dir to %s\n", buf);
index b9902e425f096f336f93c97aa2a4494508de4272..189d0bafa91ae0f274c2813f912012679f53903d 100644 (file)
@@ -249,11 +249,22 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
        DECLARE_MAC_BUF(mbuf);
        u8 *mac;
 
+       sta->debugfs.add_has_run = true;
+
        if (!stations_dir)
                return;
 
        mac = print_mac(mbuf, sta->sta.addr);
 
+       /*
+        * This might fail due to a race condition:
+        * When mac80211 unlinks a station, the debugfs entries
+        * remain, but it is already possible to link a new
+        * station with the same address which triggers adding
+        * it to debugfs; therefore, if the old station isn't
+        * destroyed quickly enough the old station's debugfs
+        * dir might still be around.
+        */
        sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
        if (!sta->debugfs.dir)
                return;
index 8025b294588bc0e1c44b61bfb465085cb0184c84..156e42a003ae77ac38e77aa1e047d58575e87eec 100644 (file)
@@ -816,8 +816,8 @@ struct ieee802_11_elems {
        u8 *ext_supp_rates;
        u8 *wmm_info;
        u8 *wmm_param;
-       u8 *ht_cap_elem;
-       u8 *ht_info_elem;
+       struct ieee80211_ht_cap *ht_cap_elem;
+       struct ieee80211_ht_addt_info *ht_info_elem;
        u8 *mesh_config;
        u8 *mesh_id;
        u8 *peer_link;
@@ -844,8 +844,6 @@ struct ieee802_11_elems {
        u8 ext_supp_rates_len;
        u8 wmm_info_len;
        u8 wmm_param_len;
-       u8 ht_cap_elem_len;
-       u8 ht_info_elem_len;
        u8 mesh_config_len;
        u8 mesh_id_len;
        u8 peer_link_len;
index 49f86fa56bff396adfc99daf8c921be3517a8cfb..87665d7bb4f9aa0bad666295914edca3dfefa701 100644 (file)
@@ -1348,10 +1348,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
            (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
                struct ieee80211_ht_bss_info bss_info;
                ieee80211_ht_cap_ie_to_ht_info(
-                               (struct ieee80211_ht_cap *)
                                elems.ht_cap_elem, &sta->sta.ht_info);
                ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                               (struct ieee80211_ht_addt_info *)
                                elems.ht_info_elem, &bss_info);
                ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
        }
@@ -1709,7 +1707,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                struct ieee80211_ht_bss_info bss_info;
 
                ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                               (struct ieee80211_ht_addt_info *)
                                elems.ht_info_elem, &bss_info);
                changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
                                               &bss_info);
index 8e6685e7ae8595569582ecdf7ea67340da79f2fa..416bb41099f361159d0bc578533d08a371a7de03 100644 (file)
@@ -388,7 +388,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
        bss = ieee80211_bss_info_update(sdata->local, rx_status,
                                        mgmt, skb->len, &elems,
                                        freq, beacon);
-       ieee80211_rx_bss_put(sdata->local, bss);
+       if (bss)
+               ieee80211_rx_bss_put(sdata->local, bss);
 
        dev_kfree_skb(skb);
        return RX_QUEUED;
index 9b72d15bc8dcb7c12978c607e057a67626c482c1..7fef8ea1f5ecf53eaf5b1596479ef1d8a834b348 100644 (file)
@@ -635,7 +635,12 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
 
                spin_lock_irqsave(&local->sta_lock, flags);
                list_for_each_entry(tmp, &local->sta_list, list) {
-                       if (!tmp->debugfs.dir) {
+                       /*
+                        * debugfs.add_has_run will be set by
+                        * ieee80211_sta_debugfs_add regardless
+                        * of what else it does.
+                        */
+                       if (!tmp->debugfs.add_has_run) {
                                sta = tmp;
                                __sta_info_pin(sta);
                                break;
index a6b51862a89d2b8fc46ab9bdf7ff8fc2e27d89df..168a39a298bdc1f754de9ad1d0ac04f311466d33 100644 (file)
@@ -300,6 +300,7 @@ struct sta_info {
                struct dentry *inactive_ms;
                struct dentry *last_seq_ctrl;
                struct dentry *agg_status;
+               bool add_has_run;
        } debugfs;
 #endif
 
index f32561ec224ca4fb1ec6a83a53d0b59dc7d63451..cee4884b9d06215f86b73630362fae1f9ab87168 100644 (file)
@@ -529,12 +529,12 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                        elems->ext_supp_rates_len = elen;
                        break;
                case WLAN_EID_HT_CAPABILITY:
-                       elems->ht_cap_elem = pos;
-                       elems->ht_cap_elem_len = elen;
+                       if (elen >= sizeof(struct ieee80211_ht_cap))
+                               elems->ht_cap_elem = (void *)pos;
                        break;
                case WLAN_EID_HT_EXTRA_INFO:
-                       elems->ht_info_elem = pos;
-                       elems->ht_info_elem_len = elen;
+                       if (elen >= sizeof(struct ieee80211_ht_addt_info))
+                               elems->ht_info_elem = (void *)pos;
                        break;
                case WLAN_EID_MESH_ID:
                        elems->mesh_id = pos;
index 7e0d53abde24bb9e10b86e55d1112b76eaa63331..742f811ca416e5b16701ce2ae49f582ed32317a6 100644 (file)
@@ -775,7 +775,7 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
         * configure it here */
 
        if (local->ops->set_frag_threshold)
-               local->ops->set_frag_threshold(
+               return local->ops->set_frag_threshold(
                        local_to_hw(local),
                        local->fragmentation_threshold);
 
index 03591d37b9cc661f2b28b8d26b23aade24482781..b92df5c1dfcf395078ca2f766f57206f2ffad047 100644 (file)
@@ -115,7 +115,7 @@ int nf_conntrack_acct_init(struct net *net)
 
        if (net_eq(net, &init_net)) {
 #ifdef CONFIG_NF_CT_ACCT
-               printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n");
+       printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Please use\n");
                printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n");
                printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n");
 #endif
index 27de3c7b006e6fe5bc72e775b62b6a78db886bc3..622d7c671cb78533082f9bf0b655a3bbffcd2f92 100644 (file)
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_extend.h>
 #include <net/netfilter/nf_conntrack_acct.h>
+#include <net/netfilter/nf_nat.h>
 
 #define NF_CONNTRACK_VERSION   "0.5.0"
 
+unsigned int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+                                 enum nf_nat_manip_type manip,
+                                 struct nlattr *attr) __read_mostly;
+EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
+
 DEFINE_SPINLOCK(nf_conntrack_lock);
 EXPORT_SYMBOL_GPL(nf_conntrack_lock);
 
index cadfd15b44f61457b54ea0291cd7c44e0b405df3..08e82d64eb6f4db6aad440c14f39ad7efd09f29a 100644 (file)
@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
        return 0;
 }
 
-#ifdef CONFIG_NF_NAT_NEEDED
-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 },
-};
-
-static int nfnetlink_parse_nat_proto(struct nlattr *attr,
-                                    const struct nf_conn *ct,
-                                    struct nf_nat_range *range)
-{
-       struct nlattr *tb[CTA_PROTONAT_MAX+1];
-       const struct nf_nat_protocol *npt;
-       int err;
-
-       err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
-       if (err < 0)
-               return err;
-
-       npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
-       if (npt->nlattr_to_range)
-               err = npt->nlattr_to_range(tb, range);
-       nf_nat_proto_put(npt);
-       return err;
-}
-
-static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
-       [CTA_NAT_MINIP]         = { .type = NLA_U32 },
-       [CTA_NAT_MAXIP]         = { .type = NLA_U32 },
-};
-
-static inline int
-nfnetlink_parse_nat(struct nlattr *nat,
-                   const struct nf_conn *ct, struct nf_nat_range *range)
-{
-       struct nlattr *tb[CTA_NAT_MAX+1];
-       int err;
-
-       memset(range, 0, sizeof(*range));
-
-       err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
-       if (err < 0)
-               return err;
-
-       if (tb[CTA_NAT_MINIP])
-               range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
-
-       if (!tb[CTA_NAT_MAXIP])
-               range->max_ip = range->min_ip;
-       else
-               range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
-
-       if (range->min_ip)
-               range->flags |= IP_NAT_RANGE_MAP_IPS;
-
-       if (!tb[CTA_NAT_PROTO])
-               return 0;
-
-       err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-#endif
-
 static inline int
 ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
 {
@@ -878,6 +813,34 @@ out:
        return err;
 }
 
+static int
+ctnetlink_parse_nat_setup(struct nf_conn *ct,
+                         enum nf_nat_manip_type manip,
+                         struct nlattr *attr)
+{
+       typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
+
+       parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
+       if (!parse_nat_setup) {
+#ifdef CONFIG_KMOD
+               rcu_read_unlock();
+               nfnl_unlock();
+               if (request_module("nf-nat-ipv4") < 0) {
+                       nfnl_lock();
+                       rcu_read_lock();
+                       return -EOPNOTSUPP;
+               }
+               nfnl_lock();
+               rcu_read_lock();
+               if (nfnetlink_parse_nat_setup_hook)
+                       return -EAGAIN;
+#endif
+               return -EOPNOTSUPP;
+       }
+
+       return parse_nat_setup(ct, manip, attr);
+}
+
 static int
 ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
 {
@@ -897,31 +860,6 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
                /* ASSURED bit can only be set */
                return -EBUSY;
 
-       if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
-#ifndef CONFIG_NF_NAT_NEEDED
-               return -EOPNOTSUPP;
-#else
-               struct nf_nat_range range;
-
-               if (cda[CTA_NAT_DST]) {
-                       if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
-                                               &range) < 0)
-                               return -EINVAL;
-                       if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
-                               return -EEXIST;
-                       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
-               }
-               if (cda[CTA_NAT_SRC]) {
-                       if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
-                                               &range) < 0)
-                               return -EINVAL;
-                       if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
-                               return -EEXIST;
-                       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
-               }
-#endif
-       }
-
        /* Be careful here, modifying NAT bits can screw up things,
         * so don't let users modify them directly if they don't pass
         * nf_nat_range. */
@@ -929,6 +867,31 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
        return 0;
 }
 
+static int
+ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
+{
+#ifdef CONFIG_NF_NAT_NEEDED
+       int ret;
+
+       if (cda[CTA_NAT_DST]) {
+               ret = ctnetlink_parse_nat_setup(ct,
+                                               IP_NAT_MANIP_DST,
+                                               cda[CTA_NAT_DST]);
+               if (ret < 0)
+                       return ret;
+       }
+       if (cda[CTA_NAT_SRC]) {
+               ret = ctnetlink_parse_nat_setup(ct,
+                                               IP_NAT_MANIP_SRC,
+                                               cda[CTA_NAT_SRC]);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+#else
+       return -EOPNOTSUPP;
+#endif
+}
 
 static inline int
 ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
@@ -1157,6 +1120,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
                }
        }
 
+       if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
+               err = ctnetlink_change_nat(ct, cda);
+               if (err < 0) {
+                       rcu_read_unlock();
+                       goto err;
+               }
+       }
+
        if (cda[CTA_PROTOINFO]) {
                err = ctnetlink_change_protoinfo(ct, cda);
                if (err < 0) {
index 373e51e91ce5bb07176ff87cf883309c616aa880..1bc3001d182773e33872081d4b40fc7bf6f4e95d 100644 (file)
@@ -65,7 +65,7 @@ void
                             struct nf_conntrack_expect *exp) __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
 
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
 /* PptpControlMessageType names */
 const char *const pptp_msg_name[] = {
        "UNKNOWN_MESSAGE",
index b75c9c4a995d885c1ac12339b0afff9d1d24db31..4739f9f961d8ea7e306021251b1676248318f72a 100644 (file)
@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL;
 static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
 static DEFINE_MUTEX(nfnl_mutex);
 
-static inline void nfnl_lock(void)
+void nfnl_lock(void)
 {
        mutex_lock(&nfnl_mutex);
 }
+EXPORT_SYMBOL_GPL(nfnl_lock);
 
-static inline void nfnl_unlock(void)
+void nfnl_unlock(void)
 {
        mutex_unlock(&nfnl_mutex);
 }
+EXPORT_SYMBOL_GPL(nfnl_unlock);
 
 int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
 {
@@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                return 0;
 
        type = nlh->nlmsg_type;
+replay:
        ss = nfnetlink_get_subsys(type);
        if (!ss) {
 #ifdef CONFIG_KMOD
@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                } else
                        return -EINVAL;
 
-               return nc->call(nfnl, skb, nlh, cda);
+               err = nc->call(nfnl, skb, nlh, cda);
+               if (err == -EAGAIN)
+                       goto replay;
+               return err;
        }
 }
 
index 24fdd4cd22cb0a0ee2708d1c96b71fb416fd503b..5031db7b275b734b46870089765420c75c136d10 100644 (file)
@@ -184,7 +184,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
        if (result)
                goto out_unlock;
 
-       if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
+       if (rdev->wiphy.debugfsdir &&
+           !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
                            rdev->wiphy.debugfsdir,
                            rdev->wiphy.debugfsdir->d_parent,
                            newname))
@@ -317,6 +318,8 @@ int wiphy_register(struct wiphy *wiphy)
        drv->wiphy.debugfsdir =
                debugfs_create_dir(wiphy_name(&drv->wiphy),
                                   ieee80211_debugfs_dir);
+       if (IS_ERR(drv->wiphy.debugfsdir))
+               drv->wiphy.debugfsdir = NULL;
 
        res = 0;
 out_unlock:
index ea48b82a37076123c09c04346f796bc8e68da5db..b4ca38a2115883294c49255769953519fb1c1ca4 100644 (file)
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
 modname_flags  = $(if $(filter 1,$(words $(modname))),\
                  -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
 
+#hash values
+ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
+              -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
+else
+debug_flags =
+endif
+
 orig_c_flags   = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
 _c_flags       = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
 _a_flags       = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
@@ -121,7 +129,8 @@ endif
 
 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
                 $(__c_flags) $(modkern_cflags) \
-                -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
+                -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
+                 $(debug_flags)
 
 a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
                 $(__a_flags) $(modkern_aflags)
index 4c324a1f1e0efb8668b4d64e05b56e8e0f64f25b..09559951df1208e00f5a51efa1208145a87efe14 100644 (file)
@@ -9,7 +9,7 @@
 # fixdep:       Used to generate dependency information during build process
 # docproc:      Used in Documentation/DocBook
 
-hostprogs-y    := fixdep docproc
+hostprogs-y    := fixdep docproc hash
 always         := $(hostprogs-y)
 
 # fixdep is needed to compile other host programs
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
new file mode 100644 (file)
index 0000000..3299ad7
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DYNAMIC_DEBUG_HASH_BITS 6
+
+static const char *program;
+
+static void usage(void)
+{
+       printf("Usage: %s <djb2|r5> <modname>\n", program);
+       exit(1);
+}
+
+/* djb2 hashing algorithm by Dan Bernstein. From:
+ * http://www.cse.yorku.ca/~oz/hash.html
+ */
+
+unsigned int djb2_hash(char *str)
+{
+       unsigned long hash = 5381;
+       int c;
+
+       c = *str;
+       while (c) {
+               hash = ((hash << 5) + hash) + c;
+               c = *++str;
+       }
+       return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
+}
+
+unsigned int r5_hash(char *str)
+{
+       unsigned long hash = 0;
+       int c;
+
+       c = *str;
+       while (c) {
+               hash = (hash + (c << 4) + (c >> 4)) * 11;
+               c = *++str;
+       }
+       return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
+}
+
+int main(int argc, char *argv[])
+{
+       program = argv[0];
+
+       if (argc != 3)
+               usage();
+       if (!strcmp(argv[1], "djb2"))
+               printf("%d\n", djb2_hash(argv[2]));
+       else if (!strcmp(argv[1], "r5"))
+               printf("%d\n", r5_hash(argv[2]));
+       else
+               usage();
+       exit(0);
+}
+
index bc6779398229757a94a44a4d3ef4a70dbf618a49..e30bac141b21ee1894f62135b8727efa276fe38e 100755 (executable)
@@ -9,7 +9,7 @@ use strict;
 my $P = $0;
 $P =~ s@.*/@@g;
 
-my $V = '0.21';
+my $V = '0.24';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -66,6 +66,7 @@ if ($#ARGV < 0) {
 my $dbg_values = 0;
 my $dbg_possible = 0;
 my $dbg_type = 0;
+my $dbg_attr = 0;
 for my $key (keys %debug) {
        eval "\${dbg_$key} = '$debug{$key}';"
 }
@@ -112,7 +113,10 @@ our $Attribute     = qr{
                        const|
                        __read_mostly|
                        __kprobes|
-                       __(?:mem|cpu|dev|)(?:initdata|init)
+                       __(?:mem|cpu|dev|)(?:initdata|init)|
+                       ____cacheline_aligned|
+                       ____cacheline_aligned_in_smp|
+                       ____cacheline_internodealigned_in_smp
                  }x;
 our $Modifier;
 our $Inline    = qr{inline|__always_inline|noinline};
@@ -142,6 +146,11 @@ our $UTF8  = qr {
        |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
 }x;
 
+our $typeTypedefs = qr{(?x:
+       (?:__)?(?:u|s|be|le)(?:\d|\d\d)|
+       atomic_t
+)};
+
 our @typeList = (
        qr{void},
        qr{(?:unsigned\s+)?char},
@@ -155,7 +164,6 @@ our @typeList = (
        qr{float},
        qr{double},
        qr{bool},
-       qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
        qr{struct\s+$Ident},
        qr{union\s+$Ident},
        qr{enum\s+$Ident},
@@ -175,6 +183,7 @@ sub build_types {
                        (?:$Modifier\s+|const\s+)*
                        (?:
                                (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
+                               (?:$typeTypedefs\b)|
                                (?:${all}\b)
                        )
                        (?:\s+$Modifier|\s+const)*
@@ -331,7 +340,7 @@ sub sanitise_line {
                        $off++;
                        next;
                }
-               if (substr($line, $off, 2) eq '*/') {
+               if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
                        $sanitise_quote = '';
                        substr($res, $off, 2, "$;$;");
                        $off++;
@@ -404,6 +413,7 @@ sub ctx_statement_block {
                # context.
                if ($off >= $len) {
                        for (; $remain > 0; $line++) {
+                               last if (!defined $lines[$line]);
                                next if ($lines[$line] =~ /^-/);
                                $remain--;
                                $loff = $len;
@@ -669,6 +679,22 @@ sub ctx_has_comment {
        return ($cmt ne '');
 }
 
+sub raw_line {
+       my ($linenr, $cnt) = @_;
+
+       my $offset = $linenr - 1;
+       $cnt++;
+
+       my $line;
+       while ($cnt) {
+               $line = $rawlines[$offset++];
+               next if (defined($line) && $line =~ /^-/);
+               $cnt--;
+       }
+
+       return $line;
+}
+
 sub cat_vet {
        my ($vet) = @_;
        my ($res, $coded);
@@ -782,9 +808,9 @@ sub annotate_values {
                        }
                        $type = 'N';
 
-               } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
+               } elsif ($cur =~ /^(if|while|for)\b/o) {
                        print "COND($1)\n" if ($dbg_values > 1);
-                       $av_pending = 'N';
+                       $av_pending = 'E';
                        $type = 'N';
 
                } elsif ($cur =~/^(case)/o) {
@@ -792,7 +818,7 @@ sub annotate_values {
                        $av_pend_colon = 'C';
                        $type = 'N';
 
-               } elsif ($cur =~/^(return|else|goto)/o) {
+               } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
                        print "KEYWORD($1)\n" if ($dbg_values > 1);
                        $type = 'N';
 
@@ -858,7 +884,7 @@ sub annotate_values {
                        print "CLOSE($1)\n" if ($dbg_values > 1);
                        $type = 'N';
 
-               } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&(?!\&))/o) {
+               } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
                        my $variant;
 
                        print "OPV($1)\n" if ($dbg_values > 1);
@@ -892,12 +918,22 @@ sub annotate_values {
 sub possible {
        my ($possible, $line) = @_;
 
-       print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1);
-       if ($possible !~ /^(?:$Modifier|$Storage|$Type|DEFINE_\S+)$/ &&
-           $possible ne 'goto' && $possible ne 'return' &&
-           $possible ne 'case' && $possible ne 'else' &&
-           $possible ne 'asm' && $possible ne '__asm__' &&
-           $possible !~ /^(typedef|struct|enum)\b/) {
+       print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
+       if ($possible !~ /(?:
+               ^(?:
+                       $Modifier|
+                       $Storage|
+                       $Type|
+                       DEFINE_\S+|
+                       goto|
+                       return|
+                       case|
+                       else|
+                       asm|__asm__|
+                       do
+               )$|
+               ^(?:typedef|struct|enum)\b
+           )/x) {
                # Check for modifiers.
                $possible =~ s/\s*$Storage\s*//g;
                $possible =~ s/\s*$Sparse\s*//g;
@@ -915,6 +951,8 @@ sub possible {
                        push(@typeList, $possible);
                }
                build_types();
+       } else {
+               warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
        }
 }
 
@@ -954,6 +992,33 @@ sub CHK {
        }
 }
 
+sub check_absolute_file {
+       my ($absolute, $herecurr) = @_;
+       my $file = $absolute;
+
+       ##print "absolute<$absolute>\n";
+
+       # See if any suffix of this path is a path within the tree.
+       while ($file =~ s@^[^/]*/@@) {
+               if (-f "$root/$file") {
+                       ##print "file<$file>\n";
+                       last;
+               }
+       }
+       if (! -f _)  {
+               return 0;
+       }
+
+       # It is, so see if the prefix is acceptable.
+       my $prefix = $absolute;
+       substr($prefix, -length($file)) = '';
+
+       ##print "prefix<$prefix>\n";
+       if ($prefix ne ".../") {
+               WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr);
+       }
+}
+
 sub process {
        my $filename = shift;
 
@@ -991,6 +1056,7 @@ sub process {
 
        # suppression flags
        my %suppress_ifbraces;
+       my %suppress_whiletrailers;
 
        # Pre-scan the patch sanitizing the lines.
        # Pre-scan the patch looking for any __setup documentation.
@@ -1025,9 +1091,14 @@ sub process {
                        # edge is a close comment then we must be in a comment
                        # at context start.
                        my $edge;
-                       for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) {
-                               next if ($line =~ /^-/);
-                               ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
+                       my $cnt = $realcnt;
+                       for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
+                               next if (defined $rawlines[$ln - 1] &&
+                                        $rawlines[$ln - 1] =~ /^-/);
+                               $cnt--;
+                               #print "RAW<$rawlines[$ln - 1]>\n";
+                               ($edge) = (defined $rawlines[$ln - 1] &&
+                                       $rawlines[$ln - 1] =~ m@(/\*|\*/)@);
                                last if (defined $edge);
                        }
                        if (defined $edge && $edge eq '*/') {
@@ -1075,6 +1146,7 @@ sub process {
                $linenr++;
 
                my $rawline = $rawlines[$linenr - 1];
+               my $hunk_line = ($realcnt != 0);
 
 #extract the line range in the file after the patch is applied
                if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1090,6 +1162,7 @@ sub process {
                        $prev_values = 'E';
 
                        %suppress_ifbraces = ();
+                       %suppress_whiletrailers = ();
                        next;
 
 # track the line number as we move through the hunk, note that
@@ -1125,7 +1198,7 @@ sub process {
                        $realfile = $1;
                        $realfile =~ s@^[^/]*/@@;
 
-                       if ($realfile =~ m@include/asm/@) {
+                       if ($realfile =~ m@^include/asm/@) {
                                ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
                        }
                        next;
@@ -1159,6 +1232,20 @@ sub process {
                                $herecurr) if (!$emitted_corrupt++);
                }
 
+# Check for absolute kernel paths.
+               if ($tree) {
+                       while ($line =~ m{(?:^|\s)(/\S*)}g) {
+                               my $file = $1;
+
+                               if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
+                                   check_absolute_file($1, $herecurr)) {
+                                       #
+                               } else {
+                                       check_absolute_file($file, $herecurr);
+                               }
+                       }
+               }
+
 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
                if (($realfile =~ /^$/ || $line =~ /^\+/) &&
                    $rawline !~ m/^$UTF8*$/) {
@@ -1171,11 +1258,8 @@ sub process {
                        ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
                }
 
-#ignore lines being removed
-               if ($line=~/^-/) {next;}
-
-# check we are in a valid source file if not then ignore this hunk
-               next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+# ignore non-hunk lines and lines being removed
+               next if (!$hunk_line || $line =~ /^-/);
 
 #trailing whitespace
                if ($line =~ /^\+.*\015/) {
@@ -1186,6 +1270,10 @@ sub process {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
                        ERROR("trailing whitespace\n" . $herevet);
                }
+
+# check we are in a valid source file if not then ignore this hunk
+               next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+
 #80 column limit
                if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
                    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
@@ -1200,8 +1288,8 @@ sub process {
                        WARN("adding a line without newline at end of file\n" . $herecurr);
                }
 
-# check we are in a valid source file *.[hc] if not then ignore this hunk
-               next if ($realfile !~ /\.[hc]$/);
+# check we are in a valid source file C or perl if not then ignore this hunk
+               next if ($realfile !~ /\.(h|c|pl)$/);
 
 # at the beginning of a line any tabs must come first and anything
 # more than 8 must use tabs.
@@ -1211,15 +1299,18 @@ sub process {
                        ERROR("code indent should use tabs where possible\n" . $herevet);
                }
 
+# check we are in a valid C source file if not then ignore this hunk
+               next if ($realfile !~ /\.(h|c)$/);
+
 # check for RCS/CVS revision markers
                if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
                        WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
                }
 
 # Check for potential 'bare' types
-               my ($stat, $cond, $line_nr_next, $remain_next);
+               my ($stat, $cond, $line_nr_next, $remain_next, $off_next);
                if ($realcnt && $line =~ /.\s*\S/) {
-                       ($stat, $cond, $line_nr_next, $remain_next) =
+                       ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
                                ctx_statement_block($linenr, $realcnt, 0);
                        $stat =~ s/\n./\n /g;
                        $cond =~ s/\n./\n /g;
@@ -1240,7 +1331,7 @@ sub process {
                                possible($type, "A:" . $s);
 
                        # definitions in global scope can only start with types
-                       } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) {
+                       } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
                                possible($1, "B:" . $s);
                        }
 
@@ -1294,10 +1385,6 @@ sub process {
                                ERROR("switch and case should be at the same indent\n$hereline$err");
                        }
                }
-               if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
-                   $line !~ /\G(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$/g) {
-                       ERROR("trailing statements should be on next line\n" . $herecurr);
-               }
 
 # if/while/etc brace do not go on next line, unless defining a do while loop,
 # or if that brace on the next line is for something else
@@ -1338,6 +1425,91 @@ sub process {
                        }
                }
 
+# Check relative indent for conditionals and blocks.
+               if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
+                       my ($s, $c) = ($stat, $cond);
+
+                       substr($s, 0, length($c), '');
+
+                       # Make sure we remove the line prefixes as we have
+                       # none on the first line, and are going to readd them
+                       # where necessary.
+                       $s =~ s/\n./\n/gs;
+
+                       # Find out how long the conditional actually is.
+                       my @newlines = ($c =~ /\n/gs);
+                       my $cond_lines = 1 + $#newlines;
+
+                       # We want to check the first line inside the block
+                       # starting at the end of the conditional, so remove:
+                       #  1) any blank line termination
+                       #  2) any opening brace { on end of the line
+                       #  3) any do (...) {
+                       my $continuation = 0;
+                       my $check = 0;
+                       $s =~ s/^.*\bdo\b//;
+                       $s =~ s/^\s*{//;
+                       if ($s =~ s/^\s*\\//) {
+                               $continuation = 1;
+                       }
+                       if ($s =~ s/^\s*?\n//) {
+                               $check = 1;
+                               $cond_lines++;
+                       }
+
+                       # Also ignore a loop construct at the end of a
+                       # preprocessor statement.
+                       if (($prevline =~ /^.\s*#\s*define\s/ ||
+                           $prevline =~ /\\\s*$/) && $continuation == 0) {
+                               $check = 0;
+                       }
+
+                       my $cond_ptr = -1;
+                       $continuation = 0;
+                       while ($cond_ptr != $cond_lines) {
+                               $cond_ptr = $cond_lines;
+
+                               # If we see an #else/#elif then the code
+                               # is not linear.
+                               if ($s =~ /^\s*\#\s*(?:else|elif)/) {
+                                       $check = 0;
+                               }
+
+                               # Ignore:
+                               #  1) blank lines, they should be at 0,
+                               #  2) preprocessor lines, and
+                               #  3) labels.
+                               if ($continuation ||
+                                   $s =~ /^\s*?\n/ ||
+                                   $s =~ /^\s*#\s*?/ ||
+                                   $s =~ /^\s*$Ident\s*:/) {
+                                       $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
+                                       $s =~ s/^.*?\n//;
+                                       $cond_lines++;
+                               }
+                       }
+
+                       my (undef, $sindent) = line_stats("+" . $s);
+                       my $stat_real = raw_line($linenr, $cond_lines);
+
+                       # Check if either of these lines are modified, else
+                       # this is not this patch's fault.
+                       if (!defined($stat_real) ||
+                           $stat !~ /^\+/ && $stat_real !~ /^\+/) {
+                               $check = 0;
+                       }
+                       if (defined($stat_real) && $cond_lines > 1) {
+                               $stat_real = "[...]\n$stat_real";
+                       }
+
+                       #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
+
+                       if ($check && (($sindent % 8) != 0 ||
+                           ($sindent <= $indent && $s ne ''))) {
+                               WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
+                       }
+               }
+
                # Track the 'values' across context and added lines.
                my $opline = $line; $opline =~ s/^./ /;
                my ($curr_values, $curr_vars) =
@@ -1363,6 +1535,15 @@ sub process {
                        }
                        next;
                }
+# TEST: allow direct testing of the attribute matcher.
+               if ($dbg_attr) {
+                       if ($line =~ /^.\s*$Attribute\s*$/) {
+                               ERROR("TEST: is attr\n" . $herecurr);
+                       } elsif ($dbg_attr > 1 && $line =~ /^.+($Attribute)/) {
+                               ERROR("TEST: is not attr ($1 is)\n". $herecurr);
+                       }
+                       next;
+               }
 
 # check for initialisation to aggregates open brace on the next line
                if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
@@ -1395,13 +1576,14 @@ sub process {
                if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
                    ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
                        my $name = $1;
-                       if (($prevline !~ /^}/) &&
-                          ($prevline !~ /^\+}/) &&
-                          ($prevline !~ /^ }/) &&
-                          ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) &&
-                          ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) &&
-                          ($prevline !~ /^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(/) &&
-                          ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) {
+                       if ($prevline !~ /(?:
+                               ^.}|
+                               ^.DEFINE_$Ident\(\Q$name\E\)|
+                               ^.DECLARE_$Ident\(\Q$name\E\)|
+                               ^.LIST_HEAD\(\Q$name\E\)|
+                               ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
+                               \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)
+                           )/x) {
                                WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
                        }
                }
@@ -1422,6 +1604,7 @@ sub process {
                if ($line =~ /\btypedef\s/ &&
                    $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
                    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
+                   $line !~ /\b$typeTypedefs\b/ &&
                    $line !~ /\b__bitwise(?:__|)\b/) {
                        WARN("do not add new typedefs\n" . $herecurr);
                }
@@ -1493,11 +1676,13 @@ sub process {
 
 # check for spacing round square brackets; allowed:
 #  1. with a type on the left -- int [] a;
-#  2. at the beginning of a line for slice initialisers -- [0..10] = 5,
+#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
+#  3. inside a curly brace -- = { [0...10] = 5 }
                while ($line =~ /(.*?\s)\[/g) {
                        my ($where, $prefix) = ($-[1], $1);
                        if ($prefix !~ /$Type\s+$/ &&
-                           ($where != 0 || $prefix !~ /^.\s+$/)) {
+                           ($where != 0 || $prefix !~ /^.\s+$/) &&
+                           $prefix !~ /{\s+$/) {
                                ERROR("space prohibited before open square bracket '['\n" . $herecurr);
                        }
                }
@@ -1632,7 +1817,7 @@ sub process {
                                # unary operator, or a cast
                                } elsif ($op eq '!' || $op eq '~' ||
                                         $opv eq '*U' || $opv eq '-U' ||
-                                        $opv eq '&U') {
+                                        $opv eq '&U' || $opv eq '&&U') {
                                        if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
                                                ERROR("space required before that '$op' $at\n" . $hereptr);
                                        }
@@ -1785,7 +1970,26 @@ sub process {
 
 # Check for illegal assignment in if conditional -- and check for trailing
 # statements after the conditional.
-               if ($line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
+               if ($line =~ /do\s*(?!{)/) {
+                       my ($stat_next) = ctx_statement_block($line_nr_next,
+                                               $remain_next, $off_next);
+                       $stat_next =~ s/\n./\n /g;
+                       ##print "stat<$stat> stat_next<$stat_next>\n";
+
+                       if ($stat_next =~ /^\s*while\b/) {
+                               # If the statement carries leading newlines,
+                               # then count those as offsets.
+                               my ($whitespace) =
+                                       ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
+                               my $offset =
+                                       statement_rawlines($whitespace) - 1;
+
+                               $suppress_whiletrailers{$line_nr_next +
+                                                               $offset} = 1;
+                       }
+               }
+               if (!defined $suppress_whiletrailers{$linenr} &&
+                   $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
                        my ($s, $c) = ($stat, $cond);
 
                        if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
@@ -1800,57 +2004,16 @@ sub process {
                        if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
                            $c !~ /}\s*while\s*/)
                        {
-                               ERROR("trailing statements should be on next line\n" . $herecurr);
-                       }
-               }
-
-# Check relative indent for conditionals and blocks.
-               if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
-                       my ($s, $c) = ($stat, $cond);
-
-                       substr($s, 0, length($c), '');
+                               # Find out how long the conditional actually is.
+                               my @newlines = ($c =~ /\n/gs);
+                               my $cond_lines = 1 + $#newlines;
 
-                       # Make sure we remove the line prefixes as we have
-                       # none on the first line, and are going to readd them
-                       # where necessary.
-                       $s =~ s/\n./\n/gs;
-
-                       # We want to check the first line inside the block
-                       # starting at the end of the conditional, so remove:
-                       #  1) any blank line termination
-                       #  2) any opening brace { on end of the line
-                       #  3) any do (...) {
-                       my $continuation = 0;
-                       my $check = 0;
-                       $s =~ s/^.*\bdo\b//;
-                       $s =~ s/^\s*{//;
-                       if ($s =~ s/^\s*\\//) {
-                               $continuation = 1;
-                       }
-                       if ($s =~ s/^\s*\n//) {
-                               $check = 1;
-                       }
-
-                       # Also ignore a loop construct at the end of a
-                       # preprocessor statement.
-                       if (($prevline =~ /^.\s*#\s*define\s/ ||
-                           $prevline =~ /\\\s*$/) && $continuation == 0) {
-                               $check = 0;
-                       }
-
-                       # Ignore the current line if its is a preprocessor
-                       # line.
-                       if ($s =~ /^\s*#\s*/) {
-                               $check = 0;
-                       }
-
-                       my (undef, $sindent) = line_stats("+" . $s);
-
-                       ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s>\n";
+                               my $stat_real = raw_line($linenr, $cond_lines);
+                               if (defined($stat_real) && $cond_lines > 1) {
+                                       $stat_real = "[...]\n$stat_real";
+                               }
 
-                       if ($check && (($sindent % 8) != 0 ||
-                           ($sindent <= $indent && $s ne ''))) {
-                               WARN("suspect code indent for conditional statements\n" . $herecurr);
+                               ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real);
                        }
                }
 
@@ -1877,6 +2040,15 @@ sub process {
                                ERROR("trailing statements should be on next line\n" . $herecurr);
                        }
                }
+# case and default should not have general statements after them
+               if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
+                   $line !~ /\G(?:
+                       (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
+                       \s*return\s+
+                   )/xg)
+               {
+                       ERROR("trailing statements should be on next line\n" . $herecurr);
+               }
 
                # Check for }<nl>else {, these must be at the same
                # indent level to be relevant to each other.
@@ -1913,12 +2085,17 @@ sub process {
 
 #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
                if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
-                       my $checkfile = "include/linux/$1.h";
-                       if (-f "$root/$checkfile" && $realfile ne $checkfile &&
+                       my $file = "$1.h";
+                       my $checkfile = "include/linux/$file";
+                       if (-f "$root/$checkfile" &&
+                           $realfile ne $checkfile &&
                            $1 ne 'irq')
                        {
-                               WARN("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
-                                       $herecurr);
+                               if ($realfile =~ m{^arch/}) {
+                                       CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+                               } else {
+                                       WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+                               }
                        }
                }
 
@@ -1953,8 +2130,8 @@ sub process {
                        # Extract the remainder of the define (if any) and
                        # rip off surrounding spaces, and trailing \'s.
                        $rest = '';
-                       while ($off != 0 || ($cnt > 0 && $rest =~ /(?:^|\\)\s*$/)) {
-                               #print "ADDING $off <" . substr($lines[$ln - 1], $off) . ">\n";
+                       while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
+                               #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
                                if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
                                        $rest .= substr($lines[$ln - 1], $off) . "\n";
                                        $cnt--;
@@ -1978,9 +2155,10 @@ sub process {
                        $dstat =~ s/\s*$//s;
 
                        # Flatten any parentheses and braces
-                       while ($dstat =~ s/\([^\(\)]*\)/1/) {
-                       }
-                       while ($dstat =~ s/\{[^\{\}]*\}/1/) {
+                       while ($dstat =~ s/\([^\(\)]*\)/1/ ||
+                              $dstat =~ s/\{[^\{\}]*\}/1/ ||
+                              $dstat =~ s/\[[^\{\}]*\]/1/)
+                       {
                        }
 
                        my $exceptions = qr{
@@ -2003,6 +2181,7 @@ sub process {
                                if ($dstat ne '' &&
                                    $dstat !~ /^(?:$Ident|-?$Constant)$/ &&
                                    $dstat !~ /$exceptions/ &&
+                                   $dstat !~ /^\.$Ident\s*=/ &&
                                    $dstat =~ /$Operators/)
                                {
                                        ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
@@ -2103,10 +2282,10 @@ sub process {
                        }
                        if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
                                my $herectx = $here . "\n";;
-                               my $end = $linenr + statement_rawlines($block) - 1;
+                               my $cnt = statement_rawlines($block);
 
-                               for (my $ln = $linenr - 1; $ln < $end; $ln++) {
-                                       $herectx .= $rawlines[$ln] . "\n";;
+                               for (my $n = 0; $n < $cnt; $n++) {
+                                       $herectx .= raw_line($linenr, $n) . "\n";;
                                }
 
                                WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
@@ -2281,6 +2460,7 @@ sub process {
                my $string;
                while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
                        $string = substr($rawline, $-[1], $+[1] - $-[1]);
+                       $string =~ s/%%/__/g;
                        if ($string =~ /(?<!%)%L[udi]/) {
                                WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
                                last;
index 622cd37a011817f3a4edd94cca5bf12a78faa281..a0f223c13f663ac9f65c92b706aa44ecde4e55cf 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef __SOUNDBUS_H
 #define __SOUNDBUS_H
 
-#include <asm/of_device.h>
+#include <linux/of_device.h>
 #include <sound/pcm.h>
 #include <linux/list.h>
 
index 8af467df9245823a2ea5c96981e161d42ed63734..ef2352c2e45116a824f4e8275e590a2c7394594b 100644 (file)
@@ -549,9 +549,9 @@ int snd_card_register(struct snd_card *card)
                return -EINVAL;
 #ifndef CONFIG_SYSFS_DEPRECATED
        if (!card->card_dev) {
-               card->card_dev = device_create_drvdata(sound_class, card->dev,
-                                                      MKDEV(0, 0), NULL,
-                                                      "card%i", card->number);
+               card->card_dev = device_create(sound_class, card->dev,
+                                              MKDEV(0, 0), NULL,
+                                              "card%i", card->number);
                if (IS_ERR(card->card_dev))
                        card->card_dev = NULL;
        }
index c0685e2f0afa1fe39cab14cf86cb733cbaa761e7..44a69bb8d4f018e953cf0de692a9fb681a4a74b0 100644 (file)
@@ -274,9 +274,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
                return minor;
        }
        snd_minors[minor] = preg;
-       preg->dev = device_create_drvdata(sound_class, device,
-                                         MKDEV(major, minor),
-                                         private_data, "%s", name);
+       preg->dev = device_create(sound_class, device, MKDEV(major, minor),
+                                 private_data, "%s", name);
        if (IS_ERR(preg->dev)) {
                snd_minors[minor] = NULL;
                mutex_unlock(&sound_mutex);
index 7d89c081a0866bfe9b7ee22696ee286007cb0a2a..61aaedae6b7e084f8d7359d28fc88d9e4493e490 100644 (file)
@@ -560,19 +560,18 @@ static int __init oss_init(void)
        sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
 
        for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
-               device_create_drvdata(sound_class, NULL,
-                                     MKDEV(SOUND_MAJOR, dev_list[i].minor),
-                                     NULL, "%s", dev_list[i].name);
+               device_create(sound_class, NULL,
+                             MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL,
+                             "%s", dev_list[i].name);
 
                if (!dev_list[i].num)
                        continue;
 
                for (j = 1; j < *dev_list[i].num; j++)
-                       device_create_drvdata(sound_class, NULL,
-                                             MKDEV(SOUND_MAJOR,
-                                                   dev_list[i].minor + (j*0x10)),
-                                             NULL,
-                                             "%s%d", dev_list[i].name, j);
+                       device_create(sound_class, NULL,
+                                     MKDEV(SOUND_MAJOR,
+                                           dev_list[i].minor + (j*0x10)),
+                                     NULL, "%s%d", dev_list[i].name, j);
        }
 
        if (sound_nblocks >= 1024)
index 4ae07e236b36a81d87a51307a9272b50cef17528..faef87a9bc3fdbac4f5ed27040877de887db6783 100644 (file)
@@ -220,9 +220,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
        else
                sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
 
-       device_create_drvdata(sound_class, dev,
-                             MKDEV(SOUND_MAJOR, s->unit_minor),
-                             NULL, s->name+6);
+       device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
+                     NULL, s->name+6);
        return r;
 
  fail: